2

我有一个“uniqueCheck”指令,它检查值是否已经存在于列表中,并相应地验证 ngModel。该指令在输入标签上使用时按预期工作,但在呈现输入标签的指令上使用时,结果与预期不符。

指令中的验证器函数被调用,但它不会验证或使输入的 ngModel 无效。
您可以在提供的 plnkr 链接上查看指令的完整代码

plnkr 链接: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>
4

2 回答 2

2

您正在创建 2 个单独ngModel的实例,它们都在输入更改时更新。

第一个是由它<input>自己创建的,它是分配给“myform”的。这也是绑定<span>里面的错误信息的地方。my-wrapper

第二个是由my-wrapper指令创建的——它是附加了验证器的那个。

如果您检查控制台(对于下面的 plnkr)并检查输入更改时验证器输出的值,您可以看到ngModel与验证器ngModel关联的值与与表单关联的值不同。但是当输入发生变化时,两者实际上都在更新。

页面加载后清除控制台,然后在更改第一个输入时检查输出。

http://plnkr.co/edit/nz6ODOVpn6lJlb055Svs?p=preview


为什么会这样?

因为两个ng-model指令都传递了相同的字符串('values.abc'),然后根据范围对其进行评估以确定它们应该监视和更新哪个对象属性 - 即双向绑定。

因此,当您更改输入时,您正在scope.values.abc通过输入ngModel实例更改 的值。此更改由实例拾取my-wrapper ngModel- 因为它正在查看相同的对象属性 - 然后验证自身。

您无法以这种方式解决问题,因为ngModel指令需要一个字符串,而不是另一个ngModel实例。


解决方案

您可以将属性从my-wrapperat inputcompile 转移:

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]);
            }
        }
    }
});

http://plnkr.co/edit/m2TV4BZKuyHz3JuLjHrY?p=preview

于 2014-12-19T12:32:11.790 回答
0

不要在 myWrapper 指令中使用范围,它会创建一个单独的变量范围。此外,您需要使用 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' : '='}
  }

});

于 2014-12-19T10:12:43.220 回答