Marzo 2018

Volume 33 Numero 3

Il presente articolo è stato tradotto automaticamente.

The Working Programmer - Come usare MEAN: Convalida Angular

Dal Ted Neward | 2018 marzo

Ted NewardBentornato nuovamente, MEANers.

Nella colonna precedente, ho avviato esaminando il supporto del angolare per form e l'input. Fatturazione superiore, ma un significato come convalidare l'input si verifica un binding bidirezionale, ovvero per essere certi che altoparlanti hanno first e un cognome, ad esempio e non solo stringhe vuote, ovvero è stata tralasciata. In mese questo, è necessario risolvere che, poiché l'input dei dati senza convalida fondamentalmente è semplicemente chiedendo agli utenti di pour garbage al sistema, lasciando all'utente di ordinare gli.

E che, come la maggior parte degli Stati Uniti, sarebbe non valida. Ad esempio, marchio livelli di davvero, Really Bad™.

SpeakerUI, il ritorno

Nell'ultima colonna, è possibile ditched il componente SpeakerEdit a favore SpeakerUI, che esegue il wrapping intorno a un'istanza del modello altoparlante e SA, ovvero in base a ciò che viene passato al suo interno, ovvero se è in uno stato di sola lettura per la visualizzazione l'altoparlante o uno stato modificabile. Usa due sezioni < div > (uno dei quali è nascosto a seconda dello stato componente è in) per mantenere l'interfaccia utente distinct (vedere figura 1). La sezione di sola lettura e non richiede la convalida, naturalmente, perché non sono presenti input utente; è la sezione modificabile che riguarda us qui.

Figura 1 il componente SpeakerUI

<form #speakerForm="ngForm">
  <div [hidden]="readonly">
    FirstName: <input name="firstName" type="text"
      [(ngModel)]="model.firstName"><br>
    LastName:  <input name="lastName" type="text"
      [(ngModel)]="model.lastName"><br>
      Subjects: {{model.subjects}}<br>
    <button (click)="save()"
      [disabled]="!speakerForm.form.dirty">Save</button>
    <button (click)="cancel()"
      [disabled]="!cancellable(speakerForm)">Cancel</button>
    <br><span>{{diagnostic}}</span>
  </div>
  ...
</form>

La prima cosa da notare è che tra il mese ultimo e ciò, spostata la logica per determinare se o meno la modalità di modifica può essere annullata (si noti come il pulsante di annullamento del disattivato proprietà associato) a un metodo sul componente stesso. Può trattarsi di un bit di eccessivi in questo caso specifico, ma consente di illustrare un aspetto importante della angolare: non è necessario eseguire tutta la logica dell'interfaccia utente direttamente all'interno del modello stesso. La logica di annullamento deve diventare complicata, visto che nel modello è probabilmente una buona idea, ma è necessario che l'oggetto modulo (l'oggetto speakerForm definito ultimo mese) disponibili per l'utilizzo nel codice del componente.

Che richiede l'utilizzo di un nuovo modulo, uno che non sono già presenti nel componente: NgForm.

NgForm

NgForm è una classe definita in angolare in modo specifico per l'utilizzo di form. È inclusa in un modulo separato dal resto della Angular core, pertanto richiede un'importazione autonomo da recuperare:

import { NgForm } from '@angular/forms';

Quando si lavora con i form in fase di esecuzione, angolare costruisce una raccolta di oggetti che rappresenta i diversi controlli e dello stesso form e lo usa per eseguire la convalida e altre attività di elaborazione. Questa raccolta di oggetti viene spesso nascosto dietro le quinte per praticità, ma sia sempre disponibile per gli sviluppatori angolari.

Una volta passato al metodo annullabile, è possibile utilizzare l'oggetto modulo per esaminare lo stato del form tramite un numero di proprietà. NgForm dirty, definisce le proprietà non valide, incontaminate, interessate, invariate e valide per rappresentare un intero spettro di stati diverse l'interazione dell'utente con il modulo. A scopo dimostrativo, aggiungeranno alcune righe di diagnostica più all'area modificabile della maschera:

<br>Pristine: {{speakerForm.form.pristine}}
Dirty: {{speakerForm.form.dirty}}
Touched: {{speakerForm.form.touched}}
Untouched: {{speakerForm.form.untouched}}
Invalid: {{speakerForm.form.invalid}}
Valid: {{speakerForm.form.valid}}

Questi semplicemente verrà visualizzato lo stato di ognuno di questi come l'utente interagisce con il modulo e spiegare cosa ognuna rappresenta. Ad esempio, "rimangono invariati" significa: piuttosto letteralmente, ovvero l'utente non è ancora interessate il form in alcun modo. Semplicemente facendo clic su (o toccare su un dispositivo mobile) la modifica in modo che viene visualizzato il cursore è sufficiente per eseguire il rendering del modulo in corso "interessate." Tuttavia, se non digita ha avuto luogo, anche se il form è "toccato", è ancora "nuovo". E così via.

Validità, come prevedibile, suggerisce che l'utente ha violato un tipo di vincolo di immissione di dati che lo sviluppatore è obbligatoria. Angular è simile alla compilazione da vincoli di validità standard HTML5, in tal caso, ad esempio, se si decide che altoparlanti devono avere sia un nome un nome e cognome, è possibile semplicemente utilizzano l'attributo "required" in campi di modifica:

FirstName: <input name="firstName" type="text"
  [(ngModel)]="model.firstName" required><br>
LastName:  <input name="lastName" type="text"
  [(ngModel)]="model.lastName" required><br>

Specificati, se l'utente modifica una voce esistente e Cancella entrambi il nome o cognome modifica campo completamente, lo stato non valido consente di capovolgere su true e lo stato valido su false, perché angolare riconosce che il flag richiesto sia presente. Ciò premesso, se angolare non serve a qualsiasi altro elemento, ovvero impostazione predefinita, angolare non fornisce l'interfaccia utente integrata per indicare che il modulo non è valido. È attivo per lo sviluppatore può segnalare all'utente in modo che il campo che richiede attenzione. Questa operazione può essere eseguita in svariati modi, tutti i dipendenti da ciò che lo sviluppatore utilizza per il supporto dell'interfaccia utente. Ad esempio, è comune quando si utilizza il framework Bootstrap CSS per contrassegnare il campo del form che richiedono attenzione da colorazione è (o una parte di esso) rosso. Non è in alternativa, spesso di avere un testo nascosto span di sotto o dopo il campo che verrà visualizzato quando vengono violati i vincoli in qualche modo e tie l'intervallo del nascosto attributo per lo stato del modulo.

Ma che genera un punto di piccole, ovvero si preferisce sapere quale controllo all'interno del form non è valido, in modo che è possibile collegare il feedback direttamente a tale controllo. Fortunatamente, la NgForm dispone di una proprietà di controlli, ovvero una matrice di oggetti NgControl, e ogni controllo definita all'interno del form (ad esempio firstName e lastName) sarà disponibile un'istanza di NgControl per rappresentarlo. Di conseguenza, è possibile fare riferimento gli oggetti di controllo direttamente nell'espressione del modello dell'attributo nascosto:

FirstName: <input name="firstName" type="text"
  [(ngModel)]="model.firstName" required>
<span [hidden]="speakerForm.controls.firstName.valid">
  Speakers must have a first name</span><br>
LastName:  <input name="lastName" type="text"
  [(ngModel)]="model.lastName" required>
<span [hidden]="speakerForm.controls.firstName.valid">
  Speakers must have a first name</span><br>

La sincerità delle risposte obbligherà me comunque molto interessante che questo codice è verificato un problema meno evidente, durante l'esecuzione, genererà alcuni errori in fase di esecuzione. Che dipende dal fatto durante le fasi meno recente del componente di NgForm non è stata costruita la raccolta di oggetti NgControl e pertanto l'espressione, speakerForm.controls.firstName, saranno non definiti.

Il modo più semplice per evitare questo problema consiste nel definire una variabile del modello locale per il controllo, anziché passare a matrice di controlli del form e usare * ngIf direttive per il test per verificare se il form è dirty o interessate e in tal caso, se è valido :

FirstName: <input name="firstName" type="text"
  [(ngModel)]="model.firstName" #firstName="ngModel"
  required>
<div *ngIf="firstName.invalid &&
            (firstName.dirty || firstName.touched)">
  <div *ngIf="firstName.errors.required">
    A first name is required.
  </div>
</div>

In pratica, ciò Elimina la necessità di lavoro tramite il speakerForm, ma è utile sapere che l'oggetto speakerForm sia accessibile da noi in fase di esecuzione, ma con alcune raccomandazioni.

Convalida personalizzata

In tali situazioni in cui lo standard HTML5 non definisce una convalida è preferibile o necessario, Angular consente di scrivere un validator personalizzato che può essere richiamato per testare il campo in questione. Ad esempio, molti anni, si supponga che ho riscontrato un'esperienza negativa con relatore denominato Josh. Non mi piace Josh. Non è mai stato. Non è importante consentire di guy che faccia parte del database, pertanto si desidera che un validator del modulo personalizzata che impedisce l'input specifico. (Ovviamente, questo è un esempio abbastanza pedantic, ma i concetti contengono praticamente qualsiasi tipo di convalida che è stato possibile immaginare).

Ad esempio la convalida, angolare potrebbe voler provare e "toccare" alla sintassi HTML quanto possibile, il che significa che validator anche personalizzato verrà visualizzato come validator HTML5, pertanto il validator forbiddenName dovrebbe essere visualizzato come qualsiasi altra regola di convalida HTML:

FirstName: <input name="firstName" type="text"
  [(ngModel)]="model.firstName" #firstName="ngModel"
  required forbiddenName="josh">

All'interno del modello, è possibile aggiungere semplicemente i necessari * direttiva ngIf per verificare se il modulo contiene il nome non consentito specificato e in tal caso, visualizzare un messaggio di errore specifico:

<div *ngIf="firstName.invalid &&
            (firstName.dirty || firstName.touched)">
  <div *ngIf="firstName.errors.required">
    A first name is required.
  </div>
  <div *ngIf="firstName.errors.forbiddenName">
    NO JOSH!
  </div>
</div>

Perfetto. Che devono mantenere out qualsiasi altoparlanti indesiderati (esaminando è Josh).

Direttive di Validator personalizzato

Per ottenere questo risultato, angolare richiede scrivere il validator come una direttiva Angular, ovvero un modo per associare una parte di codice a un elemento di sintattici ricerca HTML, ad esempio la direttiva forbiddenName nel campo di input, oppure l'obbligatorio o persino angolare * ngIf. Le direttive sono molto potenti e piuttosto oltre la chat che ho qui per esplorare completamente. Ma è opportuno almeno illustrare come validator del lavoro, questo inizia creando una nuova direttiva using "ng generare direttiva ForbiddenValidator" nella riga di comando e fare in modo che lo scaffolding non è consentito-validator.directive.ts:

import { Directive } from '@angular/core';
@Directive({
  selector: '[appForbiddenValidator]'
})
export class ForbiddenValidatorDirective {
  constructor() { }
}

Il selettore nel @Directive è riportata la sintassi che si desidera utilizzare nei modelli di HTML e Francamente, appForbiddenValidator non ottenere il cuore NASCAR. Deve essere un valore leggermente più chiaro nel relativo utilizzo, ad esempio forbiddenName. Inoltre, la direttiva deve toccare nella raccolta di convalide esistente, ovvero senza entrare troppa dettaglio, il parametro provider per il @Directive contiene boilerplate necessario per rendere disponibile al più grande di ForbiddenValidatorDirective raccolta di istanze di convalida:

@Directive({
  selector: '[forbiddenName]',
  providers: [{provide: NG_VALIDATORS,
               useExisting: ForbiddenValidatorDirective,
               multi: true}]
})

Successivamente, è necessario implementare l'interfaccia Validator, che fornisce un singolo metodo, convalidare, quale la direttiva, ovvero come potrebbe essere individuato, viene richiamato quando la convalida deve essere eseguita. Tuttavia, il risultato della funzione di convalida non è un tipo di risultato superato/non superato la convalida, ma la funzione da utilizzare per eseguire la convalida se stesso:

export class ForbiddenValidatorDirective implements Validator {
  @Input() forbiddenName: string;
  validate(control: AbstractControl): {[key: string]: any} {
    if (this.forbiddenName) {
      const nameRe = new RegExp(this.forbiddenName, 'i');
      const forbidden = nameRe.test(control.value);
      return forbidden ? {'forbiddenName': {value: control.value}} : null;
    } else {
      return null;
    }
  }
}

Fondamentalmente, angolare illustra in dettaglio un elenco di validator e se tutte le implementazioni restituiscono null, quindi tutto ciò che viene kosher e tutti gli input sono considerati validi. Se uno di essi restituisce un valore diverso da quello, considerati come parte del set di errori di convalida e aggiunto alla raccolta di errori che il modello a cui fa riferimento il * istruzioni ngIf in precedenza.

Se il validator ha un valore forbiddenName, vale a dire ciò che viene passato dall'utilizzo della direttiva, non esiste la convalida da eseguire, ovvero l'input del componente viene usato per costruire un'istanza di RegExp (tramite "i" per trovare una corrispondenza tra maiuscole e minuscole) e quindi il RegExp test (metodo) viene utilizzato per verificare se il valore del controllo corrisponde la name-which-shall-not-be-accepted. In caso affermativo, viene creato un set con la chiave forbiddenName (ossia ciò che il modello utilizzava in precedenza per determinare se un messaggio di errore, prestare attenzione) e il valore di input del controllo. In caso contrario, vengono generati gli indicatori di direttiva nuovamente null e il resto del validator del form. Se tutti gli elementi d' nuovamente null, tutto ciò che è legalmente.

Conclusioni

Supporto della convalida del angolare è, come si può vedere, piuttosto complessa e completa. Verrà creato di fuori di supporto della convalida HTML standard che è presente in ogni browser HTML5, ma fornisce un livello di supporto per il controllo di runtime che è estendibile e potente quando necessario. La maggior parte delle applicazioni saranno possibile trovare i validator predefiniti siano sufficienti per la maggior parte dei casi, ma la capacità di creare un validator personalizzato mezzo angolare può essere complesse, ad esempio necessario quando si lavora con input dell'utente. (Che è valida, poiché gli utenti visualizzeranno costantemente nuovi modi per tentare di accedere garbage al sistema. È possibile incolpare Josh per che.) Esistono tuttavia alcune altre sorprese nascondere all'interno del modulo "@angular/forms" prima è stata completata in questo caso, in questo caso presto.

Buona codifica!


Ted Newardè un consulente polytechnology basate su Seattle, altoparlante e mentor, lavorando come director delle relazioni per sviluppatori in Smartsheet.com. Egli ha scritto una considerevole quantità di articoli, creati e una dozzina libri e pronuncia in tutto il mondo. È possibile contattarlo in ted@tedneward.com o leggere il suo blog all'indirizzo blogs.tedneward.com.

Grazie all'esperto tecnico Microsoft seguente: Garvice Eakins


Viene illustrato in questo articolo nel forum di MSDN Magazine