2017-08-07 45 views
2

我有一个自定义窗体控件组件(它是一个荣耀的输入)。它是一个自定义组件的原因是为了简化UI更改 - 即,如果我们改变了我们基本上对输入控件进行样式设计的方式,则可以轻松地在整个应用程序中传播更改。在Angular中继承使用ControlValueAccessor的验证

目前,我们在角https://material.angular.io

哪些样式控制非常漂亮,当他们是无效的使用材料设计。

我们已经实现了ControlValueAccessor以允许我们将formControlName传递给我们的自定义组件,该功能完美无缺;当自定义控件有效/无效并且应用程序按预期运行时,表单有效/无效。

但是,问题在于我们需要根据自定义组件是否无效来对UI进行样式设置,而我们似乎无法做到这一点 - 实际需要样式化的输入是从未验证过,它只是将数据传递给父组件并从父组件传递数据。

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> 

例如在网页上使用:

HTML:

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

TS:

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

也许这就是你一直在寻找的? https://stackoverflow.com/questions/48573931/angular-5-glue-logic-of-components-dynamically-added-to-form –

回答

1

答案在这里找到:

Get access to FormControl from the custom form component in Angular

不知道这是做的最好的方式,我想爱一个人找一个漂亮的方式,但孩子输入结合的形式以这种方式获得控制解决了我们的问题

+0

我有完全相同的问题。在获取控制器之后,您是如何管理以反映验证的? – Erex

+0

很好的指向正确的方向,但事实上,你是如何做到这一点? –

0

另外:可能被认为是肮脏的,但它的伎俩对我来说:

  1. 让你的组件实现Validator接口。 2在验证功能中,您可以使用controlcontainer访问组件的外部窗体控件。
  2. 使用变量跟踪父窗体控件(VALID/INVALID)的状态。
  3. 检查触摸。并且只有在触摸为真并且状态已更改时才对您的字段执行验证操作。