使用隔离范围从内部指令中观察ngModel

Dus*_*tin 54 javascript angularjs angularjs-directive

我试图从我的链接功能中查看我的模型值.

scope.$watch(attrs.ngModel, function() {
       console.log("Changed"); 
    });
Run Code Online (Sandbox Code Playgroud)

当我更改控制器内的模型值时,不会触发$ watch函数.

$scope.myModel = "ACT";

$timeout(function() {
   $scope.myModel = "TOTALS"; 
}, 2000);
Run Code Online (Sandbox Code Playgroud)

小提琴:http://jsfiddle.net/dkrotts/BtrZH/4/

我在这里错过了什么?

Ben*_*esh 149

您需要观看一个返回您正在观看的$ 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);
           });
        }
     };
});
Run Code Online (Sandbox Code Playgroud)

这是一个同样的想法在行动的plunker.

  • +1也为你的答案.这两个答案都是正确的.我为问题中链接的特定问题提供了一个解决方案,而你的提供了一个通用的解决方案,为那些寻找"$ watch"在ngModel中指定的方法的人提供了解决方案. (5认同)

dnc*_*253 31

问题是,你$watch荷兰国际集团attrs.ngModel等于"基于myModel".您的范围中没有绑定"myModel".你想$watch"模仿".这就是你的指令范围内的约束.见http://jsfiddle.net/BtrZH/5/


Emm*_*uel 20

正确的方法是:

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

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

    }
  };
});
Run Code Online (Sandbox Code Playgroud)

  • 我无法解释为什么它有效,就像许多代码一样.它只是:) (7认同)
  • 它的工作原理是因为每次angular检测到这个元素模型的变化时,它都会调用[$ render](https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$render)来更新它,所以这里我们替换原来的$ render函数来做我们想做的事情. (6认同)
  • @HugoBaés - 情况并非总是如此。例如,当在输入元素上使用它时,许多[输入类型](https://github.com/angular/angular.js/blob/65f800e19ec669ab7d5abbd2f6b82bf60110651a/src/ng/directive/input.js)实现 $render 来正确设置显示给用户的值 (2认同)

小智 8

这是另一种方法:

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);  
              });
           });
        }
    };
});
Run Code Online (Sandbox Code Playgroud)

这样做,你就可以通过这样的绑定来听取价值变化