[英]Watching a controller's properties from a directive in Angular
I'm trying to watch a controller's properties from it's associated directive from within the link function. 我正试图从链接函数中的相关指令中查看控制器的属性。 The controller itself is set to the 'window' object on the $scope using controllerAs;
控制器本身使用controllerAs设置为$ scope上的'window'对象; here is the directive definition:
这是指令定义:
function windowDirective() {
return {
transclude: true,
template: template,
restrict: 'E',
controller: WindowCtrl,
controllerAs: 'window',
link: function($scope, $element, $attrs, $ctrl) {
$scope.$watch('window.x', function(newValue, oldValue) {
// access x here
});
}
};
}
And here is WindowCtrl 这是WindowCtrl
'use strict';
class WindowCtrl {
move(x, y) {
this.x = x;
this.y = y;
}
}
module.exports = WindowCtrl;
move(x, y)
is being called when I drag on a child directive - it is definitely being called and this.x
and this.y
are definitely being set on WindowCtrl. 当我拖动一个子指令时
move(x, y)
正在调用move(x, y)
- 它肯定被调用,并且this.x
和this.y
肯定是在WindowCtrl上设置的。 In addition, if I console.dir
the $scope
then fire move()
a few times, I can open up the scope in chrome (because it's lazily evaluated) and see that $scope.window.x
and $scope.window.y
are indeed being set. 另外,如果我在
console.dir
$scope
然后激活move()
几次,我可以在chrome中打开范围(因为它被懒惰地评估)并且看到$scope.window.x
和$scope.window.y
确实正在确定。
However, my $scope.$watch
never actually fires aside from when it initially detects that window.x
is undefined. 但是,我的
$scope.$watch
在最初检测到window.x
未定义时从不实际触发。 Not really sure how to proceed. 不确定如何继续。 I did search and try all of the solutions I found but none of them seemed to have worked.
我确实搜索并尝试了我找到的所有解决方案,但它们似乎都没有起作用。
I'm using Angular 1.3.16. 我正在使用Angular 1.3.16。
NB: The access to WindowCtrl.move()
is only ever from within Angular's digest cycle - see below - however using $scope.$apply()
solves this. 注意:对
WindowCtrl.move()
的访问只能在Angular的摘要周期内进行 - 见下文 - 但是使用$scope.$apply()
解决了这个问题。 I'm not sure why this is the case. 我不确定为什么会这样。 Could you explain?
你能解释一下吗? The below is a directive which is nested inside of the above directive.
以下是嵌套在上述指令中的指令。 It will invoke the method at
onDrag
, which in my example points to window.move(x, y);
它将调用
onDrag
的方法,在我的例子中指向window.move(x, y);
function windowHeaderDirective() {
return {
transclude: true,
template: template,
replace: true,
require: `^${windowDirective.$name}`,
scope: {
enableClose: '=actionClose',
draggable: '=',
onDrag: '&'
},
bindToController: true,
link: function($scope, $element, $attrs, $ctrl) {
$scope.close = $ctrl.close.bind($ctrl);
let moving = false;
$element.on('mousemove', function(event) {
if(!moving) return
const { x, y } = event;
$scope.header.onDrag({ x, y });
// $scope.$apply here will fix this issue, but why? Isn't $element.on within angular's digest cycle??
});
$element.on('mousedown', function(event) {
moving = true;
});
$element.on('mouseup', function(event) {
moving = false
});
},
controller: controller,
controllerAs: 'header'
};
}
In the $watch try using a function watcher like this: 在$ watch尝试使用这样的函数观察器:
$scope.$watch(function() {
return $scope.window.x
}, ...
Self answer: 自答案:
It appears, due to my update, I answered the question myself, so; 看来,由于我的更新,我自己回答了这个问题,所以;
$element.on
does not appear to actually be in the angular digest cycle - this is fairly surprising for me, I assumed it would be. $element.on
似乎没有实际处于角度摘要周期 - 这对我来说相当令人惊讶,我认为它会是。 However, this essentially means that my code works as it should - it's just the changes to the variables on the controller are not apparent straight away. 但是,这实际上意味着我的代码应该正常工作 - 它只是控制器上变量的变化不会立即显现出来。 The way to fix this is to simply use either
ng-mousedown
et al, or $scope.$apply
in the $element.on
handler. 解决这个问题的方法是在
$element.on
处理程序中使用ng-mousedown
et al或$scope.$apply
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.