Пользовательский компонент ввода формы - PullRequest
0 голосов
/ 25 марта 2020

Я хочу создать пользовательский компонент ввода формы, который будет работать реактивно.

Я создал компонент (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 Ответ

1 голос
/ 25 марта 2020

Ваша ошибка проста - вы устанавливаете propagateChange в registerOnChange и registerOnTouched. Вместо этого присваивается значение onTouch в registerOnTouched.

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

registerOnTouched, вызываемое платформой после registerOnChange, поэтому вы генерируете сенсорные события, когда намереваетесь генерировать события изменения.

ДЕМО https://stackblitz.com/edit/angular-ve8sri

...