$watch ngModel изнутри директивы с помощью изолировать область


Я пытаюсь посмотреть значение моей модели изнутри моей функции связывания.

scope.$watch(attrs.ngModel, function() {
       console.log("Changed"); 
    });

когда я изменяю значение модели внутри моего контроллера, функция $watch не запускается.

$scope.myModel = "ACT";

$timeout(function() {
   $scope.myModel = "TOTALS"; 
}, 2000);

Скрипка:http://jsfiddle.net/dkrotts/BtrZH/4/

что мне здесь не хватает?

6 53

6 ответов:

проблема в том, что вы $watching attrs.ngModel что равно "myModel". У вас нет привязки "myModel" в вашей области видимости. Вы хотите $watch "модели". Это то, что связано в рамках вашей директивы. См.http://jsfiddle.net/BtrZH/5/

вам нужно будет посмотреть функцию, которая возвращает $modelValue вы смотрите.

следующий код показывает простой пример:

app.directive('myDirective', function (){
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
           scope.$watch(function () {
              return ngModel.$modelValue;
           }, function(newValue) {
               console.log(newValue);
           });
        }
     };
});

вот plunker той же самой идеи в действии.

правильный способ сделать это:

app.directive('myDirective', function () {
  return {
    require: 'ngModel',
    link: function (scope, element, attrs, ngModel) {

        ngModel.$render = function () {
            var newValue = ngModel.$viewValue;
            console.log(newValue)
        };

    }
  };
});

вот еще один способ сделать это:

app.directive('myDirective', function (){
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
           attrs.$observe('ngModel', function(value){ // Got ng-model bind path here
              scope.$watch(value,function(newValue){ // Watch given path for changes
                  console.log(newValue);  
              });
           });
        }
    };
});

делая это таким образом, Вы сможете слушать изменения значений с привязками, как это

Это расширение ответа @ Emmanuel выше, чтобы ответить @Martin Velez, хотя я знаю, что уже довольно поздно! (Также я пока не могу комментировать, так что если это не подходящее место для этого, извините!)

Я не уверен, какая версия Angular OP использовалась, но в Angular#1.2+ по крайней мере в официальных документах https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$render, $render отображается следующим образом:

вызывается, когда вид должен будьте в курсе. Ожидается, что пользователь директива ng-model будет реализовывать этот метод.

метод $render () вызывается в следующих ситуациях:

$rollbackViewValue() вызывается. Если мы откатываем значение представления до последнего зафиксированного значения затем $render() вызывается для обновления элемент управления вводом. Значение, на которое ссылается ng-model, изменяется программно и $modelValue и $viewValue являются в отличие от прошлого раза. Так как ng-модель не делает глубокие часы, $render () вызывается только в том случае, если значения $modelValue и $viewValue на самом деле они отличаются от их предыдущего значения.

я интерпретирую это так, что правильный способ $watch ngModel из директивы-потребовать ngModel и реализовать функцию связи, которая вводит ngModelController. Затем используйте API ngModel, встроенный в $render-on-change ($watch) или что-то еще.

есть 2 способа сделать это.

1) Вы можете использовать $attrs.[any_attribute] и установить на него любой слушатель

2) Вы можете иметь изолированную область с 2 способа привязки переменная и установить прослушиватель на нем.Если вы хотите больше,вот классная статья

http://www.w3docs.com/snippets/angularjs/bind-variable-inside-angularjs-directive-isolated-scope.html