触摸/未触摸未在自定义输入组件中更新 - Angular 2

时间:2016-07-19 00:07:03

标签: angular angular2-forms

我有一个自定义输入组件,它正在更新验证和状态,但触摸/未触摸除外。其他所有状态(原始/肮脏)都按预期工作。

这是一个掠夺者:https://plnkr.co/edit/O9KWzwhjvySnXd7vyo71

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">

感谢您的帮助!

2 个答案:

答案 0 :(得分:10)

刚刚接受了@sharpmachine的答案,这有助于解决我的问题。我只是想改进它:

不必在模板级别将blur事件绑定到onTouched()(这可能容易出错),而是可以将ControlValueAccessor公开为Directive并在那里绑定事件。

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;
  }
}

这样您就可以使用该组件,而无需在每次使用时绑定blur事件。

希望它有所帮助!

答案 1 :(得分:4)

我犯了两个错误,比如一个旋钮。所以模板必须是:

<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>

所以输入(blur)="onTouched($event)"<p *ngIf="control?.errors?.required && control?.touched">

的两件事情