2017-08-07 1 views
2

Ich habe eine benutzerdefinierte Formular-Steuerelement-Komponente (es ist eine verklärte Eingabe). Der Grund dafür, dass es sich um eine benutzerdefinierte Komponente handelt, liegt in der einfachen Änderung der Benutzeroberfläche. Wenn wir beispielsweise die Art und Weise ändern, in der wir unsere Eingabesteuerelemente grundlegend gestalten, können Änderungen problemlos über die gesamte Anwendung verteilt werden.Erben Validierung mit ControlValueAccessor in Angular

Derzeit verwenden wir Material Design in Angular https://material.angular.io

die Arten sehr gut kontrolliert, wenn sie ungültig sind.

Wir haben ControlValueAccessor implementiert, damit wir einen formControlName an unsere benutzerdefinierte Komponente übergeben können, was perfekt funktioniert; Das Formular ist gültig/ungültig, wenn das benutzerdefinierte Steuerelement gültig/ungültig ist und die Anwendung wie erwartet funktioniert. Das Problem ist, dass wir die Benutzeroberfläche innerhalb der benutzerdefinierten Komponente stylen müssen, je nachdem ob sie ungültig ist oder nicht, was wir scheinbar nicht können - die Eingabe, die tatsächlich gestylt werden muss nie validiert, es reicht einfach Daten an und von der übergeordneten Komponente.

COMPONENT.ts

import { Component, forwardRef, Input, OnInit } from '@angular/core'; 
import { 
    AbstractControl, 
    ControlValueAccessor, 
    NG_VALIDATORS, 
    NG_VALUE_ACCESSOR, 
    ValidationErrors, 
    Validator, 
} from '@angular/forms'; 

@Component({ 
    selector: 'app-input', 
    templateUrl: './input.component.html', 
    styleUrls: ['./input.component.css'], 
    providers: [ 
    { 
     provide: NG_VALUE_ACCESSOR, 
     useExisting: forwardRef(() => InputComponent), 
     multi: true 
    } 
    ] 
}) 
export class InputComponent implements OnInit, ControlValueAccessor { 
    writeValue(obj: any): void { 
    this._value = obj; 
    } 
    registerOnChange(fn: any): void { 
    this.onChanged = fn; 
    } 
    registerOnTouched(fn: any): void { 
    this.onTouched = fn; 
    } 
    setDisabledState?(isDisabled: boolean): void { 
    this.disabled = isDisabled; 
    } 

    get value() { 
    return this._value; 
    } 

    set value(value: any) { 
    if (this._value !== value) { 
     this._value = value; 
     this.onChanged(value); 
    } 
    } 

    @Input() type: string; 

    onBlur() { 
    this.onTouched(); 
    } 

    private onTouched =() => {}; 
    private onChanged = (_: any) => {}; 
    disabled: boolean; 

    private _value: any; 

    constructor() { } 

    ngOnInit() { 
    } 

} 

COMPONENT.html

<ng-container [ngSwitch]="type"> 
    <md-input-container class="full-width" *ngSwitchCase="'text'"> 
    <span mdPrefix><md-icon>lock_outline</md-icon> &nbsp; </span> 
    <input mdInput placeholder="Password" type="text" [(ngModel)]="value" (blur)="onBlur()" /> 
    </md-input-container> 
</ng-container> 

Beispiel auf Seite verwenden:

HTML:

<app-input type="text" formControlName="foo"></app-input> 

TS:

this.form = this.fb.group({ 
     foo: [null, Validators.required] 
    }); 
+0

Vielleicht haben Sie gesucht? https://stackoverflow.com/questions/48573931/angular-5-glue-logic-of-components-dynamically-added-for- –

Antwort

1

Antwort finden Sie hier:

Get access to FormControl from the custom form component in Angular

nicht sicher, dass dies der beste Weg ist, es zu tun, und ich würde jemanden lieben, eine schönere Art und Weise zu finden, aber die Bindung des Kindes Eingabe in das Formular Kontrolle auf diese Weise erhaltenen gelöst unsere Probleme

+0

Ich habe genau das gleiche Problem. Wie haben Sie die Validierung nach dem Holen des Controllers auf die Eingabe reduziert? – Erex

+0

schön in die richtige Richtung zeigend, aber in der Tat, wie hast du das gemacht? –

0

Zusätzlich: Könnte schmutzig in Betracht gezogen werden, aber es funktioniert der Trick für mich:

  1. Lassen Sie Ihre Komponente die Validator-Schnittstelle implementieren. 2 In der Validierungsfunktion gelangen Sie mit dem Controlcontainer zur äußeren Formularsteuerung Ihrer Komponente.
  2. Verfolgen Sie den Status des übergeordneten Formularsteuerelements (VALID/INVALID) mithilfe einer Variablen.
  3. überprüfen für berührt. und führen Sie Validierungsaktionen für Ihre Felder nur aus, wenn die Option "Berührungen" aktiviert ist und der Status sich geändert hat.
Verwandte Themen