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;
};
}
};
})
(还演示了只计算一次正则表达式。)
我在 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;
};
}
};
})
(还演示了只计算一次正则表达式。)