Javascript $watch ngModel 从内部指令使用隔离范围

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14693052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 17:38:07  来源:igfitidea点击:

$watch ngModel from inside directive using isolate scope

javascriptangularjsangularjs-directive

提问by Dustin

I am trying to watch my model value from inside my linking function.

我试图从我的链接函数内部观察我的模型值。

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

When I change the model value inside my controller, the $watch function is not triggered.

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

$scope.myModel = "ACT";

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

Fiddle: http://jsfiddle.net/dkrotts/BtrZH/4/

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

What am I missing here?

我在这里缺少什么?

采纳答案by dnc253

The problem is that you $watching attrs.ngModelwhich is equal to "myModel". You do not have "myModel" bound in your scope. You want to $watch"model". That is what is bound in the scope of your directive. See http://jsfiddle.net/BtrZH/5/

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

回答by Ben Lesh

You'll need to watch a function that returns the $modelValue you're watching.

您需要观看一个返回您正在观看的 $modelValue 的函数。

The following code shows a basic example:

以下代码显示了一个基本示例:

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 plunkerof the same idea in action.

这是一个在行动中具有相同想法的plunker

回答by Emmanuel

The proper way to do this is:

正确的做法是:

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

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

    }
  };
});

回答by user2978730

Here is another way to do this:

这是执行此操作的另一种方法:

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);  
              });
           });
        }
    };
});

Doing it that way you will be able to listen value changes with binds like that

这样做,您将能够通过这样的绑定监听值的变化

回答by RoboBear

This is an extension of @ Emmanuel's answer above to answer @Martin Velez, although I know it's pretty late! (Also I can't make comments yet, so if this isn't the right place for this, sorry!)

这是上面@Emmanuel 回答@Martin Velez 的延伸,尽管我知道现在已经很晚了!(另外我还不能发表评论,所以如果这不是合适的地方,对不起!)

I'm not sure which version of Angular OP was using, but in Angular#1.2+ at least on the official docs https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$render, $render is listed like this:

我不确定使用的是哪个版本的 Angular OP,但至少在官方文档https://docs.angularjs.org/api/ng/type/ngModel.NgModelController#$render 中,在 Angular#1.2+ 中是这样列出的:

Called when the view needs to be updated. It is expected that the user of the ng-model directive will implement this method.

The $render() method is invoked in the following situations:

$rollbackViewValue() is called. If we are rolling back the view value to the last committed value then $render() is called to update the input control. The value referenced by ng-model is changed programmatically and both the $modelValue and the $viewValue are different from last time. Since ng-model does not do a deep watch, $render() is only invoked if the values of $modelValue and $viewValue are actually different from their previous value.

当视图需要更新时调用。预计 ng-model 指令的用户将实现此方法。

$render() 方法在以下情况下被调用:

$rollbackViewValue() 被调用。如果我们将视图值回滚到最后提交的值,则调用 $render() 来更新输入控件。ng-model 引用的值以编程方式更改,并且 $modelValue 和 $viewValue 都与上次不同。由于 ng-model 不做深度观察,只有在 $modelValue 和 $viewValue 的值实际上与它们之前的值不同时才会调用 $render() 。

I interpret this to mean that the correct way to $watch an ngModel from a directive is to require ngModel and implement a link function that injects ngModelController. Then use the ngModel API that's built in to $render-on-change ($watch), or whatever else.

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

回答by Hazarapet Tunanyan

There are 2 ways to do it.

有 2 种方法可以做到。

1) You can use $attrs.[any_attribute]and set on it any listener

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

2) You can have isolated scope with 2 ways bindingvariable and set a listener on it.If you want more,here is a cool article

2)您可以通过两种方式绑定变量并在其上设置侦听器来隔离作用域。如果您想要更多,这里有一篇很酷的文章

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

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