我有一个“uniqueCheck”指令,它检查值是否已经存在于列表中,并相应地验证ngModel。当用于输入标签时,该指令按预期工作,但在用于呈现输入标签的指令上时,结果不符合预期。
指令内的验证器函数被调用,但它不验证或使输入的ngModel无效。
您可以在提供的plnkr链接上查看指令的完整代码
Plnkr Link:plnkr
html如下:
<--! when used with a directive -->
<my-wrapper ng-model="values.abc" unique-check="" list="list" prop="name"> </my-wrapper>
<--! when used on an input tag-->
<div ng-form="myform">
<input type="text" unique-check
list="list" prop="name"
name="myfield"
ng-model="values.pqr"/>
<span>isDuplicate:{{myform.myfield.$error.isDuplicate}}</span>
</div>
答案 0 :(得分:2)
您正在创建2个单独的ngModel
个实例,这些实例在输入更改时都会更新。
第一个是由<input>
本身创建的,这是分配给'myform'的那个。这也是<span>
中的my-wrapper
错误消息也绑定的那个。
第二个是由my-wrapper
指令创建的指令 - 它是附加了验证器的指令。
如果检查控制台(对于下面的plnkr)并在输入更改时检查验证器输出的值,您可以看到与验证器关联的ngModel
不同ngModel
。 1}}与表格相关联。但是当输入发生变化时,两者实际上都在更新。
页面加载后清除控制台,然后在更改第一个输入时检查输出。
http://plnkr.co/edit/nz6ODOVpn6lJlb055Svs?p=preview
为什么会这样?
因为两个ng-model
指令都传递了相同的字符串('values.abc'),然后根据范围对其进行评估,以确定他们应该监视和更新哪个对象属性 - 即双向绑定。
因此,当您更改输入时,您将通过输入scope.values.abc
实例更改ngModel
的值。此更改由my-wrapper
ngModel
实例获取 - 因为它正在观察相同的对象属性 - 然后验证自身。
您无法以这种方式解决问题,因为ngModel
指令需要一个字符串,而不是另一个ngModel
实例。
的解决方案强>
您可以在编译时将属性从my-wrapper
传输到input
:
app.directive("myWrapper", function(){
var templateFn = function(element, attrs){
return '<div ng-form="myform">'+
'<input type="text" name="myfield"/>'+
'<span>(inside directive) : isDuplicate:{{myform.myfield.$error.isDuplicate}}</span>'
'</div>';
}
return {
restrict :'E',
template : templateFn,
require: 'ngModel',
scope: true,
compile: function(element, attrs) {
var attr;
angular.forEach(element.find('input'), function(elem) {
elem = angular.element(elem)
for(attr in attrs.$attr) {
elem.attr(attrs.$attr[attr], attrs[attr]);
}
});
for(attr in attrs.$attr) {
element.removeAttr(attrs.$attr[attr]);
}
}
}
});
答案 1 :(得分:0)
不要在myWrapper指令中使用scope,它会创建一个单独的变量范围。此外,您需要使用element.ngModel,而不仅仅是字符串'ngModel'作为ng-model。
将这样的myWrapper指令更改为:
app.directive("myWrapper", function(){
var templateFn = function(scope, element, attrs){
return '<div ng-form="myform">'+
'<input type="text" name="myfield" ng-model="'+element.ngModel+'"/>'+
'<span>isDuplicate:{{myform.myfield.$error.isDuplicate}}</span>'
'</div>';
}
return {
restrict :'E',
template : templateFn,
//require: 'ngModel',
//scope: {'ngModel' : '='}
}
});