我想将DOM事件附加到指令元素,以便更新范围属性。不幸的是,我找不到一个“干净”的方法来做到这一点。我现在能够使用它的唯一方法是在处理程序中显式调用$apply()
。我知道这是不好的做法,但它也阻止我与本机角度指令共享此代码,例如使用ng-click="myDOMEventHandler()"
(因为它会触发$apply already in progress
异常。
有没有办法将DOM事件添加到指令元素,以便获取对范围的更改,但无需调用$apply()
?
这是我的意思的一个简单例子。 You can edit this Plunker as well)。
angular.module('myApp', [])
.directive('myDirective', function ($compile) {
return {
link: function (scope, element) {
scope.keystrokes = 0;
var report = angular.element('<div ng-click="increment()">keystrokes: {{keystrokes}}</div>');
element.after(report);
$compile(report)(scope);
scope.increment = function () {
scope.keystrokes += 1;
scope.$apply();
};
element.on('keyup', scope.increment);
}
};
});
如果在输入中输入了一些文本,则计数器会递增。如果单击该按钮,计数器也会递增 - 但如果引发$apply already in progress
异常。
如果删除scope.$apply()
,则异常消失,范围属性确实发生变化,但这些更改永远不会显示。
答案 0 :(得分:1)
您不必使用范围。$ apply在scope.increment函数内,但您应该使用
当您在角度范围之外绑定事件时,$apply
内的 element.on('keyup'...))
angular.module('myApp', [])
.directive('myDirective', function ($compile) {
return {
link: function (scope, element) {
scope.keystrokes = 0;
var report = angular.element('<div>keystrokes and clicks: {{keystrokes}} <button ng-click="increment()">Or click me</button></div>');
element.after(report);
$compile(report)(scope);
scope.increment = function () {
scope.keystrokes += 1;
};
element.on('keyup', function(){
scope.$apply(function(){
scope.increment();
});
});
}
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<input my-directive="" />
</body>