自定义表单输入组件

时间:2020-03-25 09:15:19

标签: angular angular-reactive-forms

我想创建一个自定义的表单输入组件,该组件可以进行反应。

我创建了一个组件(TS)

import { Component, forwardRef, Input, OnInit } from "@angular/core";
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";

@Component({
  selector: "app-new-input",
  templateUrl: "./new-input.component.html",
  styleUrls: ["./new-input.component.css"],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => NewInputComponent),
      multi: true
    }
  ]
})
export class NewInputComponent implements ControlValueAccessor, OnInit {
  @Input() label: string = "";
  @Input() placeholder: string = "";
  @Input() type: string = "text";

  propagateChange: any = () => {};
  onTouch: any = () => {};
  value: string = "";

  constructor() {}

  ngOnInit() {}

  onChange(event: any) {
    this.value = event.target.value;
    this.propagateChange(this.value);
  }

  writeValue(value: string): void {
    this.value = value ? value : "";
  }
  registerOnChange(fn: any): void {
    this.propagateChange = fn;
  }
  registerOnTouched(fn: any): void {
    this.propagateChange = fn;
  }
  setDisabledState?(isDisabled: boolean): void {}
}

和HTML

{{label}}

<input matInput [type]="type" [value]="value" [placeholder]="placeholder" (change)="onChange($event)" (keyup)="onChange($event)">

我的应用程序组件中有

  searchForm: FormGroup = this.formBuilder.group({
    name: [""]
  });

  constructor(private formBuilder: FormBuilder) {}

和应用程序组件HTML

<form [formGroup]="searchForm">
  <app-new-input formControlName="name"></app-new-input>
</form>

{{searchForm.value | json}}

所有这些都可以在STACKBLITZ

上找到

所以,我遇到的问题是组件输入的更改不会传播到父级(应用程序组件)形式

有人可以告诉我我在做什么错吗?

1 个答案:

答案 0 :(得分:1)

您的错误很简单-您在propagateChangeregisterOnChange中都设置了registerOnTouched。而是在onTouch中分配给registerOnTouched

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

registerOnTouched在框架registerOnChange之后被调用,因此,当您打算发出更改事件时,您将发出触摸事件。

DEMO https://stackblitz.com/edit/angular-ve8sri