Angular 表格。如何获得一些输入以重新评估其他输入?

Angular Forms. How to Get Some Inputs to Reevaluate Others?

我在 angular 中有一个表单,其中包含类别文本输入和 ID 输入。 ID 对于类别必须是唯一的。因此,如果我有 Cat1 的以下项目:

Cat1 - 123
Cat1 - 245
Cat1 - 456

然后,如果我尝试输入类别为 Cat1 且 ID 为 123 的新项目,则该输入对于该类别将不是唯一的,并且无法提交表单。如果 id 更改为 1234 则它将有效。

为了实现这一点,我有一个名为 unique 的自定义指令,它需要 ngModel。看起来像这样-

HTML-

<input name="ID"
       required
       unique="id in getItemsByCategory(newCategory)"
       type="text"
       ng-model="newId"></input>

JS-

.directive('unique', function() {
    return {
      require: '^ngModel',
      link: function(scope, ele, attr, ngModelController) {
        ngModelController.$validators.unique = function(val) {
          var uniqueInRegex = /([^\s]+)\s+in\s([^\s]+)/i;

          var matches = attr.unique.match(uniqueInRegex);
          var property = matches[1];
          var collection = scope.$eval(matches[2]);

          for(var i = 0; i < collection.length; i++) {
            var item = collection[i];
            if(item[property] === val) {
              console.log('not unique');
              return false;
            }
          }

          console.log('unique');
          return true;
        };
      }
    };
  });

哪个工作正常:

但是如果验证器根据类别发现该字段不是唯一的,并且类别字段发生变化,则验证器不会重新评估。

这是在这些 gif 中看到的内容的 JSBin:

http://jsbin.com/wubesutugo/edit?html,js,output

无论如何我可以有一个输入 "touch" 当它改变时另一个输入?我希望这个验证指令是通用的,因为我有多个地方想使用它。所以我不想在控制器中使用这个逻辑。

您使用 ng-change 的解决方案就足够了。另一种方法是使用手表($watchCollection,准确地说):

.directive('unique', function() {
    var uniqueInRegex = /([^\s]+)\s+in\s([^\s]+)/i;
    return {
      require: '^ngModel',
      link: function(scope, ele, attr, ngModelController) {
        var matches = attr.unique.match(uniqueInRegex);
        var property = matches[1];
        var collectionExpr = matches[2];

        scope.$watchCollection(collectionExpr, function(newval) {
          ngModelController.$validate();
        });

        ngModelController.$validators.unique = function(val) {
          var collection = scope.$eval(collectionExpr);
          for(var i = 0; i < collection.length; i++) {
            var item = collection[i];
            if(item[property] === val) {
              console.log('not unique');
              return false;
            }
          }

          console.log('unique');
          return true;
        };
      }
    };
})

(还演示了只计算一次正则表达式。)

试一试:http://jsbin.com/wiyugozuje/1/edit?js,console,output