Ответ 1
Я думаю, это могло бы быть вызвано тем, что метод verifyDuplicate сохраняет настройку и переопределяет допустимость той же модели, поэтому действительность вызова метода запуска модели будет основана на последнем результате сравнения в цикле.
Один из способов решения этой проблемы - позволить методу verifyDuplicate работать с коллекцией лиц в целом, независимо от того, какое изменение модели инициирует вызов метода, в этом примере метод $ setValidity не используется, вместо этого свойство isDuplicate в модели чтобы указать дублирование.
HTML:
<ng-form name="personForm">
<div ng-class="{ 'has-error' :
personForm.personName.$invalid }">
<input type='number'
name="personName"
ng-class="empty"
ng-model="person.name"
ng-change="verifyDuplicate()"/>
</div>
</ng-form>
<div class='error'
ng-if='person.isDuplicate'>
Duplicate.
</div>
JavaScript:
$scope.verifyDuplicate = function() {
var sorted, i;
sorted = $scope.persons.concat().sort(function (a, b) {
if (a.name > b.name) return 1;
if (a.name < b.name) return -1;
return 0;
});
for(i = 0; i < $scope.persons.length; i++) {
sorted[i].isDuplicate = ((sorted[i-1] && sorted[i-1].name == sorted[i].name) || (sorted[i+1] && sorted[i+1].name == sorted[i].name));
}
};
JSFiddler: http://jsfiddle.net/luislee818/pkhxkozp/4/
Если мы настаиваем на использовании $ setValidity, я могу подумать о подключении отдельной модели к ее форме с помощью директивы "ng-init", однако это выглядит громоздким, и, если мы пойдем с этим подходом, могут быть лучшие способы.
HTML:
<ng-form name="personForm">
<div ng-class="{ 'has-error' :
personForm.personName.$invalid }">
<input type='number'
name="personName"
ng-init="person.form = personForm"
ng-class="empty"
ng-model="person.name"
ng-change="verifyDuplicate()"/>
</div>
</ng-form>
<div class='error'
ng-show=
'personForm.personName.$error.duplicate'>
Duplicate.
</div>
JavaScript:
$scope.verifyDuplicate = function() {
var sorted, i, isDuplicate;
sorted = $scope.persons.concat().sort(function (a, b) {
if (a.name > b.name) return 1;
if (a.name < b.name) return -1;
return 0;
});
for(i = 0; i < $scope.persons.length; i++) {
isDuplicate = ((sorted[i-1] && sorted[i-1].name == sorted[i].name) || (sorted[i+1] && sorted[i+1].name == sorted[i].name));
sorted[i].form.personName.$setValidity('duplicate',!isDuplicate);
}
};