我一直在阅读其他人关于如何在AngularJS(1.4)中正确使用$ watch的答案,但我仍然不明白为什么我的代码不起作用。我不明白如何从指令的链接函数中查看模型值。设置scope.$watch(controller.value)
仅在值绑定到控制器之前触发(值仍未定义),稍后在值更改时不会触发。另一方面,scope.$watch(function(){return controller.value})
有效。那是为什么?
在我的示例中,我在控制器userCtrl
上有一个年龄值。我想基于btn-primary
的值将类btn-success
或controller.age
添加到按钮:以下是指令:
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');
}
});
}
}
});
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');
}
});
}
}
});
关于Plunker的演示:http://plnkr.co/edit/nFjiCzVhVJkUGY5AEM1C?p=preview
答案 0 :(得分:1)
这是因为vm.user.age
在该时间点返回的值被视为要根据范围进行评估的表达式(或此处的属性)。如果在那个时间点说值为12
,那么它会在范围内设置属性12
上的监视,这显然不是您所期望的。
您应该给出表达式的字符串表示形式(scope.$watch('userCtrl.user.age', function(newVal...
),该表达式可以根据返回值的范围或函数进行评估。当您提供userCtrl.user.age
被观看时,angular将在$parse service
的帮助下将表达式包裹在function(){
return $scope.userCtrl.user.age;
}
中,以便说出类似的内容(例如,getter函数将更复杂到解决空检查等问题。):
- (void)viewDidLoad{
[super viewDidLoad];
// add pan recognizer to the view when initialized
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panRecognized:)];
[panRecognizer setDelegate:self];
[yourView addGestureRecognizer:panRecognizer]; // add to the view you want to detect swipe on
}
-(void)panRecognized:(UIPanGestureRecognizer *)sender{
CGPoint distance = [sender translationInView: yourView];
if (sender.state == UIGestureRecognizerStateEnded) {
[sender cancelsTouchesInView];
if (distance.x > 70 && distance.y > -50 && distance.y < 50) { // right
NSLog(@"user swiped right");
NSLog(@"distance.x - %f", distance.x);
} else if (distance.x < -70 && distance.y > -50 && distance.y < 50) { //left
NSLog(@"user swiped left");
NSLog(@"distance.x - %f", distance.x);
}
if (distance.y > 0) { // down
NSLog(@"user swiped down");
NSLog(@"distance.y - %f", distance.y);
} else if (distance.y < 0) { //up
NSLog(@"user swiped up");
NSLog(@"distance.y - %f", distance.y);
}
}
}
将在消化周期中对变化检测进行评估。因此,自己提供一个吸气功能也不会造成任何伤害。