2015-10-12 21 views
6

Ho appena letto il fantastico angular page on form validation e probabilmente mi sono perso qualcosa, ma come posso applicare la proprietà ng-model-optionsdebounce a un validatore specifico.Debounce su un solo validatore

Lasciami spiegare il problema. Ho un modulo che convalida una chiave pubblica e per questo ho una direttiva chiamata key-check che contiene più validatori. Alcuni di loro sono locali e sincroni come il formato della chiave e c'è un altro asincrono che controlla se la chiave è disponibile sul server (in modo asincrono).

Non voglio il mio server per essere inondazioni né l'applicazione angolare per essere rallentato in modo che uso che i bambini freschi chiamano debouncing e il mio ingresso sembra qualcosa di simile:

<input type="text" ... ng-model="key" key-check ng-model-options="{ debounce: 700 }" ng-minlength="5" ng-maxlength="50"/> 

e la direttiva è come:

ctrl.$validators.keyFormatCheck = function(modelValue) { 
    // return boolean 
} 

ctrl.$asyncValidators.KeyAvailabilityCheck = function(modelValue) { 
    // return promise 
} 

e 'un lavoro come un fascino ma tutto il controllo sono fatti con 700ms latenza e mi chiedo se è possibile fare la keyFormatCheck, senza debouncing e la KeyAvailabilityCheck con esso. Posso probabilmente usare il vecchio buon modo con timeout $ ma preferisco farlo il modo angolare.

Qualche idea?

+0

È puoi sempre passare un parametro alla tua direttiva –

+0

Il problema non è che non posso aggiungere proprietà alla mia direttiva. Il problema è, all'interno della direttiva, come posso impostare un antirimbalzo su un validatore? –

+0

Quindi, si aggiunge un timeout $ di conseguenza –

risposta

5

ngModelController 's debounce vale per l'intera pipeline di parser, validatori e view-change-ascoltatori (ad esempio ng-change).

Oggi non è possibile (Angolare v1.4) con ngModelOptions isolare il ritardo debounce a un validatore specifico.

Ma la funzionalità è facilmente ottenibile passando un parametro di ritardo per il proprio direttiva asincrona validatore:

<input ng-model="val" foo-validator="{delay: 500}"> 

si implementa il ritardo effettivo con $timeout; nessuna ragione qui per evitare l'uso di $timeout per il fatto che è in qualche modo inferiore a "la via Angolare"; non è.

L'unico trucco è assicurarsi di annullare la precedente richiesta di convalida in attesa prima di eseguirne una nuova.

var pendingValidation; 
ngModel.$asyncValidators.foo = function(modelValue, viewValue){ 

    if (pendingValidation) $timeout.cancel(pendingValidation); 

    pendingValidation = $timeout(function(){ 
    pendingValidation = null; 

    // returns promise or value 
    return doAsyncValidation(); 
    }, delay); 

    return pendingValidation; 
}; 

delay possono essere ottenute da un parametro tramite un attributo foo-validator, sia con legame portata isolare (scope: {config: "=fooValidator"}), oppure utilizzando direttamente $eval -zione l'espressione attributo contro la portata destra:

var config = $scope.$eval(attrs.fooValidator); 
var delay = config.delay; 
+1

Ok quindi non c'è modo di applicare direttamente la proprietà debounce al validatore e non a tutta la pipeline. Immagino sia la buona risposta, anche se non è affatto soddisfacente: '( Grazie comunque –

+0

@ThomasLeduc, giusto - non c'è modo. Che sia soddisfacente o meno, puoi prenderlo con il team di Angular e suggerire un miglioramento, ma a mio avviso questo sarebbe un caso d'uso troppo ristretto per implementare un framework –

+0

Probabilmente hai ragione ... ma non è così stretto, è un caso di base, grazie comunque per la conferma. –

Problemi correlati