mdl-textfield не учитывает изменения ngModel

Я столкнулся с проблемой, связанной с поведением mdl-textfield.

На приведенном ниже plnkr выполните следующие действия:

  1. нажмите "группы работают"
  2. нажмите "копировать" на одном элементе
  3. посмотрите в самом конце появилось новое текстовое поле со связанным ngModel (angular.copy), но поведение текстового поля странное, даже если есть значение, метка не плавает, но если щелкнуть текстовое поле, оно плавает, как и ожидалось . Если вы измените поле, поведение останется, но если вы выйдете из него без каких-либо изменений, метка вернется с наложением.

http://plnkr.co/edit/MUI2iBslIH9jd4fgEQPL?p=preview

ngView содержание

<div data-ng-controller="MainCtrl">
  <section data-ng-repeat="fo in foo">
    <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
      <input class="mdl-textfield__input" type="text" id="sample1" data-ng-model="fo.bar"/>
      <label class="mdl-textfield__label" for="sample1">{{fo.bar}}</label>
      <span ng-if="$last" ng-init="update()"></span>
    </div>
    <button ng-click="focopy(fo)">Copy</button>
  </section>
    <div data-ng-show="datacopy.edit" class="input-field">
      <input type="text" id="ex1" data-ng-model="datacopy.bar" />
      <label for="ex1">label</label>
    </div>
</div>

Угловой модуль

var app=angular.module('plunker', ['ngRoute'])
app.config(function($routeProvider){
    $routeProvider
    //Root URL
    .when('/',{template:'<p>Coucou</p>'})
    .when('/groups',{templateUrl:'groups.html'})
    .when('/groupsnotworking',{templateUrl:'groupsnotworking.html'})
});

app.controller('MainCtrl', function($scope,$timeout) {
$scope.foo = [
  {bar: 'world'},{bar:'toto'},{bar:'toto'}
];
$scope.groups=$timeout(function(){
  $scope.groups=$scope.foo
},1000);
$scope.update=function(){
  componentHandler.upgradeAllRegistered();
};
$scope.datacopy={};
$scope.focopy=function(data){
  $scope.datacopy=angular.copy(data);
  $scope.datacopy.edit=true;
};
});

Надеюсь, это достаточно ясно. Я пытался опубликовать это на github облегченного дизайна материалов, думая, что это ошибка, но меня выгнали здесь... Спасибо.


person Guillaume MASSART    schedule 26.07.2015    source источник
comment
Вы сделали все, что говорит MDL для использования с динамическими сайтами? Вы должны сообщить ему о компиляции элементов, добавленных позже: getmdl.io/started/#dynamic   -  person Dylan Watt    schedule 26.07.2015
comment
Да, на плнкере вы можете увидеть кнопку обновления, запускающую функцию 'componentHandler.upgradeAllRegistered()'. В любом случае, поведение текстового поля нормальное, если учесть плавающую метку и анимацию подчеркивания.   -  person Guillaume MASSART    schedule 26.07.2015
comment
Я тестировал с Materialize, такое же поведение (менее глючное, так как нормальное поведение наступает, как только элемент управления получает фокус)   -  person Guillaume MASSART    schedule 26.07.2015


Ответы (3)


Когда вы устанавливаете значение ng-model для mdl-textfield__input после регистрации компонента mdl, mdl-textfield не получает класс is-dirty, поэтому ведет себя не так, как должен.

Вы можете использовать эту директиву в поле `mdl-textfield__input:

"use strict";
(function(){
  let mdlTfFix = () => {
    return {
      restrict: "C",
      require: "ngModel",
      link: ($scope, $element, $attrs, ngModelCtrl) => {
        $scope.$watch(() => {
          return ngModelCtrl.$modelValue;
        }, (newVal, oldVal) =>{

          if(typeof newVal !== "undefined" && newVal !== "" && newVal !== oldVal){
            $element.parent().addClass("is-dirty");
          }
          else{
            $element.parent().removeClass("is-dirty");
          }
        });
      }
    };
  };

  mdlTfFix.$inject = [];
  app.directive("mdlTextfieldInput", mdlTfFix);

})();
person MrP    schedule 24.11.2016

Вы должны вручную очистить текстовые входы MDL js, если они очищаются с помощью скрипта. Например, после очистки входного значения вызовите это mdlCleanup();.

  //MDL Text Input Cleanup
  function mdlCleanUp(){
    var mdlInputs = doc.querySelectorAll('.mdl-js-textfield');
    for (var i = 0, l = mdlInputs.length; i < l; i++) {
      mdlInputs[i].MaterialTextfield.checkDirty();
    }  
  }
person Ronnie Royston    schedule 30.12.2016

работать со мной. надеюсь, это поможет вам

function CleanMDL() {
        setTimeout(function () {
            $scope.$apply(function () {
                var x = document.getElementsByClassName("mdl-js-textfield");
                var i;
                for (i = 0; i < x.length; i++) {
                    x[i].MaterialTextfield.checkDirty();
                }
            })
        }, 100);
    }
person Chiến Trần    schedule 06.02.2018