我有两个连接在一起的指令(提供最少的代码示例):
一个用于验证目的( apValidation )。
module.directive('apValidation', ['$compile', function($compile){
return {
restrict: 'A',
compile: function (element) {
element.removeAttr('ap-validation'); // to avoid infinite compilation
element.attr('ng-blur', 'testMe()'); // this method has to be called for the validation to happen
var fn = $compile(element);
return function (scope) {
fn(scope);
};
},
controller: function ($scope, $attrs) {
$scope.testMe = function () {
alert("Validating current text field");
};
}
}
}]);
另一个是可重用的文本字段组件,定义为具有独立范围的指令,它使用验证指令( apTextField )。
module.directive('apTextField', function(){
return{
restrict: 'E',
replace:true,
scope: {
name: '@',
label: '@'
},
template: '<div>{{label}}: <input type="text" id="someId" name="{{name}}" ap-validation></input></div>'
}
});
我面临的问题是,当我在 ngRepeat 上下文中使用我的文本字段指令时,不知何故验证功能,即由此处的模糊事件触发案件,不再被召唤。 但是,验证在ngRepeat上下文之外正常工作。
<div ng-app="my-app" ng-controller="MainController">
<div>
Without ng-repeat<br>
<div ng-init="field = {name: 'age', label: 'Age'}">
<ap-text-field
label={{field.label}}
name="{{field.name}}">
</ap-text-field>
</div><br>
With ng-repeat<br>
<div ng-repeat="field in fields">
<ap-text-field
label={{field.label}}
name="{{field.name}}">
</ap-text-field>
</div>
</div>
我知道ngRepeat会创建一个新的IsolatedScope,但我不明白这会如何影响我的指令,以及这个问题的正确解决方案是什么。
我已准备好JS Fiddle来最好地描述我的问题。
答案 0 :(得分:5)
原因是ngRepeat
指令已经编译了它的转发器并将其从DOM中删除(在$ watchCollection()回调期间重新插入);因此,以下代码var fn = $compile(element);
编译从DOM中删除的元素。因此,解决方案是编译提供给返回回调的新element
:
compile: function (element) {
element.removeAttr('ap-validation'); // to avoid infinite compilation
element.attr('ng-blur', 'testMe()'); // this method has to be called for the validation to happen
return function (scope, element) {
//^ the new element
$compile(element)(scope);
};
}