2014-09-18 10 views
11

Mam sytuację, w której użytkownik musi wprowadzić dane wejściowe w obszarach tekstowych utworzonych przez ng-repeat. Jeśli użytkownik wprowadzi wartość, która została już wprowadzona, nowe i istniejące wartości powinny zostać zweryfikowane jako fałszywe. Jeśli jedna z wartości (istniejąca lub nowa) zostanie zmieniona, walidacja powinna zostać odpowiednio zaktualizowana.Angularjs - jak sprawdzić unikalne dane wejściowe i czy istnieje zduplikowany znacznik zarówno jako nieprawidłowy

Próbowałem różnych opcji, obecnie jest to, co się zbliża, ale wciąż nie jest w 100%.

HTML:

<body ng-app="ap" ng-controller="con"> 
<table> 
    <tr> 
     <td>name</td> 
    </tr> 
    <tr ng-repeat="person in persons"> 
     <td> 
      <ng-form name="personForm"> 
      <div ng-class="{ 'has-error' : 
       personForm.personName.$invalid }"> 
       <input type='text' 
       name="personName" 
       ng-class="empty" 
       ng-model="person.name" 
       ng-change="verifyDuplicate(this, person)"/> 
       </div> 
      </ng-form> 
     </td> 
    </tr> 
</table> 

JavaScript:

var app = angular.module("ap",[]); 

    app.controller("con",function($scope){ 

    $scope.persons = [ 
     {name: 'a'}, 
     {name: 'b'}, 
     {name: 'c'} 
    ]; 

    $scope.empty = "normal"; 

    $scope.verifyDuplicate = function(domScope, object){ 
     for(var i = 0; i < $scope.persons.length; i++) { 
      if($scope.persons[i].name === object.name && $scope.persons[i] !== object) { 
       domScope.personForm.personName.$setValidity('duplicate',false); 
      } 
      else { 
       domScope.personForm.personName.$setValidity('duplicate',true); 
      } 
     } 
    }; 
}); 

Każda pomoc w tej sprawie będzie mile widziane.

Oto ryba Fiddle of code

Odpowiedz

15

myślę, że to może dlatego, że verifyDuplicate metoda zachowuje ustawienie i ponowne ustawienie na ważność tego samego modelu, więc ważność modelu wyzwalania wywołania metody będą oparte na wynik ostatniego porównania w pętli.

Jednym ze sposobów rozwiązania tego problemu jest pozwolić verifyDuplicate metoda pracy na osób zbiór jako całość, bez względu na zmiany modelu wywołuje metodę wezwanie, w tym przykładzie $ setValidity metoda nie jest używany zamiast tego właściwość isDuplicate jest ustawiona tak, aby wskazywała na duplikację.

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/

Jeśli upieramy przy użyciu $ setValidity, mogę myśleć o podłączeniu indywidualny model swojej postaci z " ng-init "jednak wygląda to na uciążliwe i mogą istnieć lepsze sposoby, jeśli zastosujemy to podejście.

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

JSFiddle: http://jsfiddle.net/luislee818/nzd87f1s/1/

+0

Świetnie, będę to daje iść jak najszybciej znaleźć lukę, nadzieję, że to działa w prawdziwym problem światowy, do którego chcę go zastosować. – avn

+0

Działa świetnie, dziękuje za pomoc. – avn

+0

@ dapeng-li To działało dla mnie, ale nie było dobre dla testów jednostkowych. czy można to przekształcić w niestandardową dyrektywę walidacyjną? –

Powiązane problemy