2015-03-25 4 views
6

Ho un campo di input con un numero di $validators registrato su di esso che aggiorna il modello. Alcuni di questi validatori fanno confronti con altri valori sull'ambito (che vengono aggiornati anche con i campi di input).Come forzare la convalida per l'esecuzione sul modello quando vengono modificati altri modelli?

Come posso forzare AngularJS a eseguire nuovamente queste convalide quando gli altri valori vengono modificati su cui è dipendente?

Ho provato a trovare qualcosa relativo a questo nella documentazione e anche creato un $watch sul campo dipendente e basta impostare il valore del modello su se stesso (sperando che forzerebbe una riconvalida) ma senza fortuna su entrambi i conteggi.

+0

Condividere ciò che hai provato – mohamedrias

+0

@mohamedrias aggiornato la questione –

+0

Si prega di condividere il codice di guardare – mohamedrias

risposta

5

Se si utilizza Angularjs 1.3+ è possibile utilizzare il metodo $ validate. Diciamo che l'input "A" è quello che dipende dagli altri input, chiamiamoli "B" s. È possibile aggiungere una funzione a ciascun $ viewChangeListeners di B, che chiamerà semplicemente il metodo di convalida $ di A. Questo avrà il seguente effetto; ogni volta che modifichi uno degli input B, i tuoi input $ validatori verranno eseguiti.

+2

Esattamente quello di cui ho bisogno. Grazie! '$ scope.myForm.inputB $ viewChangeListeners.push (function() {$ scope.myForm.inputA $ validate();. });.' scriverò una direttiva per il riutilizzo, ma la il concetto è provato. –

3

So che è stata data risposta qualche tempo fa, ma ho riscontrato un problema simile e sono riuscito a creare una soluzione adatta insieme da una serie di altre risposte e un po 'di tentativi ed errori. Immagino che qualcun altro possa cercare qualcosa di simile un giorno ...

Ecco un metodo che (per quanto posso dire) si collega direttamente con il sistema di validazione. Questo particolare esempio crea una regola di convalida match, che confronta due modelli e convalida se il loro valore è identico.

<script type="text/javascript"> 
angular.module("YourModule", []) 
    .directive("match", function() { 
     return { 
      require: 'ngModel', 
      restrict: 'A', 
      link: function($scope, $elem, $attrs, $ctrl) { 

       // targetModel is the name of the model you want to 
       // compare against. 
       var targetModel = $attrs.match; 

       // Add the 'match' validation method 
       $ctrl.$validators.match = function(modelValue, viewValue) { 
        valid = $scope.$eval(targetModel) == viewValue; 
        $ctrl.$setValidity('match', valid); 
        return valid ? viewValue : undefined; 
       }; 

       // When the target model's value changes, cause this model 
       // to revalidate 
       $scope.$watch(targetModel, function() { 
        $ctrl.$validate(); 
       }); 

      } 
     }; 
    }); 

Quindi utilizzare simili (includendo ovviamente una forma, ng-app e ng-controller):

<input type="password" ng-model="password" /> 
<input type="password" ng-model="confirmation" match="password" /> 

L'idea generale è che quando la direttiva partita viene elaborato, una funzione aggiuntiva (match) viene aggiunto allo $validators sull'oggetto $ctrl, che è dove gli altri validatori (campo obbligatorio, lunghezza minima, ...) sembrano vivere. Questo imposta la convalida sul campo, ma tale regola viene elaborata solo quando il campo con la direttiva della corrispondenza viene aggiornato.

Per combattere questo, un orologio viene quindi impostato sul modello di destinazione. Quando il valore del modello di destinazione viene aggiornato, eseguirà il metodo $validate() sul controllo originale, consentendo la convalida in uno dei due campi.

Problemi correlati