2016-07-19 16 views
13

私は、検証を更新しているカスタム入力コンポーネントを持っています。状態に応じたもの(初期のもの/汚れたもの)は、期待どおりに機能します。タッチ入力/非タッチ入力がカスタム入力コンポーネントで更新されない - 角2

はここplunkerです:任意の助けhttps://plnkr.co/edit/O9KWzwhjvySnXd7vyo71

import { Component, OnInit, Input, ElementRef, forwardRef, Renderer } from '@angular/core'; 
import { REACTIVE_FORM_DIRECTIVES, Validator, Validators, NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms'; 



export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = /*@ts2dart_const*/ { 
    provide: NG_VALUE_ACCESSOR, 
    useExisting: forwardRef(() => CustomInputComponent), 
    multi: true 
}; 

const noop =() => {}; 

@Component({ 
    selector: 'my-custom-input', 
    providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR], 
    template: ` 
    <div class="form-group"> 
    <label>CUSTOM INPUT</label> 
    <input type="text" class="form-control" [(ngModel)]="value" required> 
    <p *ngIf="control.errors.required && control.touched">Field is required</p> 
    <strong>Has input been touched: {{control.touched ? 'Yes' : 'No'}}</strong><br> 
    <strong>Is input untouched: {{control.untouched ? 'Yes' : 'No'}}</strong><br> 
    <strong>Is input dirty: {{control.dirty ? 'Yes' : 'No'}}</strong> <br> 
     <strong>Is input pristine: {{control.pristine ? 'Yes' : 'No'}}</strong> 
    </div> 
    <div> 
    In Custom Component: {{value}} 
    </div> 
` 
}) 


export class CustomInputComponent implements ControlValueAccessor { 
    @Input() control; 


    // The internal data model 
    private _value: any = ''; 

    //Placeholders for the callbacks 
    private _onTouchedCallback: (_:any) => void = noop; 

    private _onChangeCallback: (_:any) => void = noop; 

    //get accessor 
    get value(): any { return this._value; }; 

    //set accessor including call the onchange callback 
    set value(v: any) { 
    if (v !== this._value) { 
     this._value = v; 
     this._onChangeCallback(v); 
    } 
    } 

    //Set touched on blur 
    onTouched(){ 
    this._onTouchedCallback(null); 
    } 

    //From ControlValueAccessor interface 
    writeValue(value: any) { 
    this._value = value; 
    } 

    //From ControlValueAccessor interface 
    registerOnChange(fn: any) { 
    this._onChangeCallback = fn; 
    } 

    //From ControlValueAccessor interface 
    registerOnTouched(fn: any) { 
    this._onTouchedCallback = fn; 
    } 

} 

ありがとう!

答えて

8

ちょうど@sharpmachine答えを踏ん

<div class="form-group"> 
    <label>CUSTOM INPUT</label> 
    <input type="text" class="form-control" [(ngModel)]="value" (blur)="onTouched($event)" required> 
    <p *ngIf="control?.errors?.required && control?.touched">Field is required</p> 

    <strong>Has input been touched: {{control.touched ? 'Yes' : 'No'}}</strong><br> 
    <strong>Is input untouched: {{control.untouched ? 'Yes' : 'No'}}</strong><br> 
    <strong>Is input dirty: {{control.dirty ? 'Yes' : 'No'}}</strong> <br> 
    <strong>Is input pristine: {{control.pristine ? 'Yes' : 'No'}}</strong> 
    </div> 
    <div> 
    In Custom Component: {{value}} 
    </div> 

だから、二つのこと、それは私の問題を解決するために助けた:だからテンプレートはする必要があります。私はちょうどそれを改善したいと思います:

代わりに、DirectiveとしてControlValueAccessorを露出させ、そこにイベントをバインドすることが可能である(エラーが発生しやすくすることができます)テンプレートレベルでonTouched()blurイベントをバインドしたの。あなたはblurイベントにあなたがそれを使用するたびにバインドすることなく、コンポーネントを使用することができるはず

import { Directive, forwardRef } from '@angular/core'; 
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; 

export const CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR: any = { 
    provide: NG_VALUE_ACCESSOR, 
    useExisting: forwardRef(() => CustomInputAccessor), 
    multi: true 
}; 

@Directive({ 
    selector: 'my-custom-input', 
    host: {'(blur)': 'onTouched($event)'}, 
    providers: [CUSTOM_INPUT_CONTROL_VALUE_ACCESSOR], 
}) 
export class CustomInputAccessor implements ControlValueAccessor { 

    // The internal data model 
    private _value: any = ''; 

    public onChange: any = (_) => { /*Empty*/ } 
    public onTouched: any =() => { /*Empty*/ } 

    get value(): any { return this._value; }; 

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

    writeValue(value: any) { 
    this._value = value; 
    } 

    registerOnChange(fn: any) { 
    this.onChange = fn; 
    } 

    registerOnTouched(fn: any) { 
    this.onTouched = fn; 
    } 
} 

この方法です。

希望すると助かります!

+0

ありがとう!非常に役立ちます! – sharpmachine

4

私はノブヘッドのように2つのミスをしていました。入力の(blur)="onTouched($event)"、および<p *ngIf="control?.errors?.required && control?.touched">

+0

もちろん!何らかの理由で私はControlValueAccessorインターフェースを実装することでそれを解決することができます。ええ。 – lukeatdesignworks

関連する問題