Angularjs 角度:在链接中,$watch(ctrl.value)不起作用,但$watch(function(){return ctrl.value})起作用。为什么?
我一直在阅读其他人关于如何在AngularJS(1.4)中正确使用$watch的答案,但我仍然不明白为什么我的代码不起作用。我不明白如何从指令的link函数中查看模型值。设置Angularjs 角度:在链接中,$watch(ctrl.value)不起作用,但$watch(function(){return ctrl.value})起作用。为什么?,angularjs,angularjs-directive,Angularjs,Angularjs Directive,我一直在阅读其他人关于如何在AngularJS(1.4)中正确使用$watch的答案,但我仍然不明白为什么我的代码不起作用。我不明白如何从指令的link函数中查看模型值。设置scope.$watch(controller.value)仅在值绑定到控制器之前触发(值仍未定义),之后在值更改时不会触发。另一方面,scope.$watch(function(){return controller.value})起作用。为什么呢 在我的示例中,控制器userCtrl上有一个年龄值。我想根据控制器的值将c
scope.$watch(controller.value)
仅在值绑定到控制器之前触发(值仍未定义),之后在值更改时不会触发。另一方面,scope.$watch(function(){return controller.value})
起作用。为什么呢
在我的示例中,控制器userCtrl
上有一个年龄值。我想根据控制器的值将classbtn primary
或btn success
添加到按钮。age
:以下是指令:
Plunker上的演示:这是因为
vm.user.age
在该时间点返回的值被视为要根据作用域计算的表达式(或属性)。如果此时说值为12
,那么它将在范围的属性12
上设置一个手表,这显然不是您所期望的
您应该给出字符串表示(scope.$watch('userCtrl.user.age',function(newVal…
)可以根据返回值的作用域或函数对表达式进行求值。当您提供要监视的userCtrl.user.age
时,angular将在$parse service
的帮助下将表达式包装在(正如示例所示,getter函数将更复杂地处理空检查等):
这将在摘要周期中进行评估,以进行更改检测。因此,自己提供getter函数也不会造成任何伤害。谢谢。
$watch('userCtrl.user.age')…
为什么起作用,但$watch('vm.user.age')…
不工作,即使我在链接函数的前面设置了vm=scope.userCtrl
。此外,$watch($parse('vm.user.age')…
不工作,但$watch('userCtrl.user.age'))…
有效。就好像跳过了vm=scope.userCtrl
。vm
只是一个变量,而不是作用域上的属性。基本上,您只是将userCtrl引用的值赋给一个变量。有趣的是,scope.$watch
无法查看局部变量,只能查看作用域对象本身内的属性。您有没有关于是否应该使用$watch('userCtrl.user.age')、$watch('parse('userCtrl.user.age')、$watch(function(){return vm.user.age}…
)或$watch(function(){return vm.age}…),有什么意见吗?这对性能有影响吗?这取决于正在监视的内容吗?第一个问题的答案是它可以监视任何东西(任何有效的角度表达式),但任何特定的属性值都将根据作用域进行计算。我已经解释过了,我相信这也是我的答案。还有,为什么需要执行$watch($parse)('userCtrl.user.age'
?watch已经使用了parse service right?就性能而言,yuo最初的方式会稍微好一点,因为angular不必为解析器创建表达式(这是任何一次性的方式)。
app.directive('myDirective',function(){
return {
restrict: 'A',
templateUrl:'my-directive.html',
bindToController: true,
controller: 'userController',
controllerAs: 'userCtrl',
scope: {user:'='}, //example: {name:'John',age:9}
link: function(scope,element,attrs){
var vm = scope.userCtrl;
var el_button = element.find('button');
//WHY IS $WATCH NOT GETTING CALLED WHEN THE AGE CHANGES?
//if we change vm.user.age to function(){return vm.user.age} things work
//but why is that any different?
scope.$watch(vm.user.age,function(newVal,oldVal){
console.log('age has changed to ' + newVal);
if(newVal > 9){
el_button.removeClass('btn-primary');
el_button.addClass('btn-success');
}else{
el_button.removeClass('btn-success');
el_button.addClass('btn-primary');
}
});
}
}
});
function(){
return $scope.userCtrl.user.age;
}