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
$watch ngModel from inside directive using isolate scope
提问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.
回答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)您可以通过两种方式绑定变量并在其上设置侦听器来隔离作用域。如果您想要更多,这里有一篇很酷的文章

