我有一个与其控制器共享数据的指令,我正在使用隔离范围。
但是,当我从指令内部更新数据时,指令和控制器都不会使用$ watch查看数据更改。
以下是我尝试做的一个例子:
var app = angular.module('myApp', []);
app.controller('myAppCtrl', function($scope) {
$scope.buttonSettings = {
val: 0
}
$scope.$watch('buttonSettings.val', function(val) {
console.log('watchInController')
console.log(val)
});
});
app.directive('buttonTest', function() {
return {
restrict: 'E',
scope: {
buttonSettings: '='
},
template: '<button>{{buttonSettings.val}}</button>',
link: function(scope) {
var button = $('button');
console.log(scope.buttonSettings)
scope.$watch('buttonSettings.val', function(val) {
console.log('watchInDirective')
console.log(val)
});
button.bind('mouseover', function() {
scope.buttonSettings.val++;
console.log('mouseover')
console.log(scope.buttonSettings.val)
})
}
}
});
以下是plunkr中的完整示例:http://plnkr.co/edit/lnztoMhtU03Qzl0BaMpk?p=preview
我做错了什么?
答案 0 :(得分:1)
首先,你不应该这样使用jQuery。您可以使用元素参数将其注入指令,而不是使用jQuery选择按钮。
其次,您需要使用 $ scope。$ apply 来触发指令和控制器中的监视。
app.directive('buttonTest', function() {
return {
scope: {
buttonSettings: '='
},
link: function(scope, element) {
element.bind('mouseover', function() {
scope.$apply(function() {
scope.buttonSettings.val++;
});
})
}
}
});
查看此工作plunker。
答案 1 :(得分:1)
halilb是正确的,你不应该使用jQuery来选择元素,而是使用Angular为你的指令提供的元素,并且需要$scope.$apply
来注册在Angular的上下文之外发生的事件。但是,您根本不需要制定新的指令来解决您的问题。只需使用Angular的ngMouseover
指令。您可以将函数绑定到它或直接添加逻辑。这是一个非常简单的例子。
<div ng-init="foo = 1">Value: {{foo}}</div>
<button ng-mouseover="foo = foo+1">Mouse over this: {{foo}}</button>
以下是移动到控制器的逻辑看起来相同的代码:
<div>Value: {{foo}}</div>
<button ng-mouseover="incrementFoo()">Mouse over this: {{foo}}</button>
控制器:
$scope.foo = 1;
$scope.incrementFoo = function() {
++$scope.foo;
};