这是我的指示:
directive('test', ['$compile', function ($compile) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.attr('ng-change', "someFunction()"); // <--- Doesnt Work
element.attr('ng-blur', "someFunction()"); // <--- Works
element.removeAttr('test');
$compile(element)(scope);
}
};
}])
Marup就是这个
<input ng-model="foo" test />
现在,正在调用blur
处理程序,而change
处理程序不是。为什么呢?
答案 0 :(得分:2)
编辑: 问题已修改,现在包含ng-model
,因此我删除了ngChange
要求{{ngModel
的原始答案1}}。现在,双重编译(以前称为&#34;非主题&#34;)是理解该问题的核心。
重要的是要认识到您正在采用的方法会导致对此元素的其他指令进行双重编译。具体而言,以下指令是有意义的:
ngModel
- 已编译/关联两次 input
- 已编译/关联两次 ngChange
- 已编译/关联一次 <强> TL; DR 强>
ngChange
不会触发处理程序,因为它运行时会认为该值没有改变,因为该值之前已更改(现在等于{的值) {1}}元素)由第一次编译产生的<input>
的第一个实例。
更长的版本:
ngModel
指令的每个编译过程都会生成ngModel
的新实例。需要ngModelController
的{{1}}指令的每个编译传递在其input
函数中获取ngModel
的不同实例,并且ngModelController
函数运行时它设置一个监听器来响应link
元素的变化。
link
仅在第二个 <input>
指令实例的ngChange
数组中注册一次。
因此,当第一个 ngModel.$viewChangeListeners
指令的监听器通知ngModel
的第一个实例时(通过input
} ngChange` listener。
但是当第一个 ngModelController
指令实例将ngModel.$setViewValue), that instance doesn't have the
设置为ngModel
元素中的值时,处理其所有$viewValue
, <input>
和$parsers
,第二 $validators
的{{1}}处理程序也将$viewChangeListerners
设置为$watch
的{{1}} } element。
然后,当最终第二个 ngModel
指令侦听器运行时,它会将$viewValue
与基础<input>
元素进行比较 - 它们是现在平等 - 并跳过input
/ $viewValue
/ <input>
的整个渠道。
$parsers
没有使用$validators
,因此它会直接侦听事件,从而触发(两次)。
<强>解决方案:强>
所以,小心双重编译。最小化这一点 - 并且绝对避免$viewChangeListeners
/ ng-blur
指令的双重编译 - 的一种方法是使用ngModel
和高于1的优先级。您可以将优先级任意提高到&#34;捕获&#34;元素上可能存在的其他指令:
ngModel