Angular Reactive Forms - лучший способ реализовать обертки входных компонентов? - PullRequest
1 голос
/ 11 июля 2019

Задача, которую я пытаюсь решить:

Создание многократно используемых оболочек компонента ввода для экономии времени при написании шаблона для форм.

Пример того, что я имею в виду:

Вместо того, чтобы писать следующий шаблон:

<form [formGroup]="myForm">
  <mat-form-field>
    <input matInput placeholder="Email" [formControl]="email" required>
    <mat-error *ngIf="email.invalid">{{getErrorMessage()}}</mat-error>
  </mat-form-field> 
<form>

Я хотел бы написать:

<form [formGroup]="myForm">
    <my-input-component [form]="myForm" [myFormControl]="email" [myFormControlName]="'email'" [label]="'Email'"></my-input-component>
</form>

Где my-input-component выглядит так:

<mat-form-field [formGroup]="form">
    <input
        matInput
        type="text"
        [attr.inputmode]="inputMode"
        [placeholder]="label"
        [formControlName]="myFormControlName"
    />
    <mat-error class="errors" *ngIf="myFormControl.invalid">
        <div>{{ getError() }}</div>
    </mat-error>
</mat-form-field>

Это работает как есть, но я не знаю, является ли это хорошим подходом для передачи FormGroup и FormControls как привязок.

После поиска в Интернете я постоянно сталкивался с NG_CONTROL_VALUE_ACCESSOR и был немного озадачен, если это можно или нужно использовать в моем сценарии.

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

Любые предложения или советы по этой теме будут с благодарностью!

1 Ответ

0 голосов
/ 14 июля 2019

Рекомендованный способ достижения этого, как вы уже узнали, реализовать интерфейс ControlValueAccessor .Этот интерфейс был создан специально для создания пользовательских элементов управления формы.Это создаст мост между вашим повторно используемым компонентом и Forms API.

Вот небольшой пример поля ввода для повторного использования с меткой.Вы также можете добавить свои сообщения об ошибках в этот шаблон.

Компонент

import { Component, OnInit, Input, Self, Optional } from '@angular/core';
import { ControlValueAccessor, NgControl } from '@angular/forms';

@Component({
  selector: 'custom-input',
  templateUrl: './custom-input.component.html',
  styleUrls: ['./custom-input.component.css']
})
export class CustomInputComponent implements OnInit, ControlValueAccessor {
  @Input() disabled: boolean;
  @Input() label: string;
  @Input() placeholder: string = '';
  @Input() type: 'text' | 'email' | 'password' = 'text';

  value: any = '';

  constructor(
    // Retrieve the dependency only from the local injector,
    // not from parent or ancestors.
    @Self()
    // We want to be able to use the component without a form,
    // so we mark the dependency as optional.
    @Optional()
    private ngControl: NgControl
  ) {
    if (this.ngControl) {
      this.ngControl.valueAccessor = this;
    }
  }

  ngOnInit() {}

  /**
   * Write form value to the DOM element (model => view)
   */
  writeValue(value: any): void {
    this.value = value;
  }

  /**
   * Write form disabled state to the DOM element (model => view)
   */
  setDisabledState(isDisabled: boolean): void {
    this.disabled = isDisabled;
  }

  /**
   * Update form when DOM element value changes (view => model)
   */
  registerOnChange(fn: any): void {
    // Store the provided function as an internal method.
    this.onChange = fn;
  }

  /**
   * Update form when DOM element is blurred (view => model)
   */
  registerOnTouched(fn: any): void {
    // Store the provided function as an internal method.
    this.onTouched = fn;
  }

  private onChange() {}
  private onTouched() {}
}

Шаблон

<label>{{ value }}</label>
<input [type]="type"
       [placeholder]="placeholder"
       [value]="value"
       [disabled]="disabled"
       (input)="onChange($event.target.value)"
       (blur)="onTouched()" />

Вы можете проверить эту статью Создание пользовательского компонента формы в Angular для получения более подробной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...