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

时间:2013-02-04 18:26:17

标签: javascript angularjs angularjs-directive

我正在尝试从链接功能中查看我的模型值。

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 个答案:

答案 0 :(得分:148)

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

Here's a plunker同样的想法在行动。

答案 1 :(得分:29)

问题是你$watch attrs.ngModel等于“myModel”。您的范围中没有绑定“myModel”。你想要$watch“模特”。这就是你的指令范围内的约束。见http://jsfiddle.net/BtrZH/5/

答案 2 :(得分:20)

这样做的正确方法是:

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

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

    }
  };
});

答案 3 :(得分: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);  
              });
           });
        }
    };
});

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

答案 4 :(得分:4)

这是@ 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-model没有深入观察,   $ render()仅在$ modelValue和$ viewValue的值时调用   实际上与以前的价值不同。

我认为这意味着从指令中观察ngModel的正确方法是要求ngModel并实现注入ngModelController的链接函数。然后使用内置于$ render-on-change($ watch)或其他任何内容的ngModel API。

答案 5 :(得分:1)

有两种方法可以做到。

1)您可以使用$attrs.[any_attribute]并在其上设置任何监听器

2)你可以使用 2种方式绑定变量来隔离范围并在其上设置一个监听器。如果你想要更多,这里有一篇很酷的文章

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