我正在尝试从链接功能中的相关指令中查看控制器的属性。控制器本身使用controllerAs设置为$ scope上的'window'对象;这是指令定义:
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
});
}
};
}
这是WindowCtrl
'use strict';
class WindowCtrl {
move(x, y) {
this.x = x;
this.y = y;
}
}
module.exports = WindowCtrl;
当我拖动一个子指令时,正在调用 move(x, y)
- 它肯定被调用,并且this.x
和this.y
肯定是在WindowCtrl上设置。另外,如果我console.dir
$scope
然后激活move()
几次,我可以在chrome中打开范围(因为它被懒惰地评估)并看到$scope.window.x
和$scope.window.y
确实已经确定。
然而,我的$scope.$watch
在最初检测到window.x
未定义时,实际上从未触发。不确定如何继续。我确实搜索并尝试了我找到的所有解决方案,但似乎都没有。
我正在使用Angular 1.3.16。
注意:只有在Angular的摘要周期内才能访问WindowCtrl.move()
- 见下文 - 但是使用$scope.$apply()
解决了这个问题。我不确定为什么会这样。你能解释一下吗?以下是嵌套在上述指令中的指令。它将调用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'
};
}
答案 0 :(得分:0)
在$ watch中尝试使用这样的函数观察器:
$scope.$watch(function() {
return $scope.window.x
}, ...
答案 1 :(得分:0)
自我回答:
看来,由于我的更新,我自己回答了这个问题,所以;
$element.on
似乎并没有真正处于角度消化周期中 - 这对我来说是相当令人惊讶的,我认为它会是。但是,这实际上意味着我的代码可以正常工作 - 它只是控制器上变量的变化不会立即显现出来。解决此问题的方法是在ng-mousedown
处理程序中使用$scope.$apply
等或$element.on
。