Как пометить formControl как затронутый, когда он оборачивается компонентом - PullRequest
0 голосов
/ 07 июня 2019

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

  <mat-form-field>
    <input matInput type="text" placeholder="{{ label }}" [(ngModel)]="_value"
           [required]="required" [disabled]="_disabled"
           (input)="intenrnalValueChange()" />
    <mat-hint>{{ hint }}</mat-hint>
    <mat-error>{{ getError() }}</mat-error>
  </mat-form-field>

Компонент работает хорошо, за исключением небольшой проблемы.Я не могу пометить его как тронутый, и я верю, что это связано с архитектурой компонентов.Я пробовал некоторые решения StackOverflow (и другие), которые хорошо работают традиционным способом, но не работают для моего компонента.

    this.form.get('field').markAsTouched(); // should work
    this.form.markAsTouched(); // should not work
    this.form.markAllAsTouched(); // should work

Я хочу отметить поле, к которому прикоснулась кнопка, которая покажетвсе поля, которые еще недействительны (и их сообщение с ошибкой mat).

Я создал упрощенный проект, где можно воспроизвести проблему.Я хочу, чтобы при нажатии кнопки поле становилось красным, а сообщение появляется ниже.Этого не происходит, но если поле щелкнуто и размыто, отображается ошибка.

https://stackblitz.com/edit/angular-7mghym

Вопрос: как изменить мой проект (сохранить компонент) в порядкечтобы кнопка имела такой же эффект, чтобы кликать и размыть поле?

1 Ответ

1 голос
/ 12 июня 2019

у вашего подхода есть несколько проблем;

прежде всего, вы реализуете ControlValueAccessor, но ваш InputComponent имеет @Input с именем formControl.В результате этого, когда вы связываете form.controls.field с app-input, ваша форма не взаимодействует с ControlValueAccessor.

<app-input label="Test" hint="It is a test" [formControl]="form.controls.field" required></app-input>

Как указано в docs ;

ControlValueAccessor действует как мост между API угловых форм и собственным элементом в DOM (элемент ввода html)

Здесь возникает вторая проблема;в InputComponent связь между DOM (элемент ввода html) и ControlValueAccessor обрабатывается через ngModel, который по сути является оберткой вокруг явно созданного FormControl под капотом.

В результате этого;form.controls.field FormControl не имеет связи с фактическим элементом ввода, ngModel имеет.Вот почему, когда вы вручную фокусируете / размытие входного элемента, он отображает состояние ошибки, но this.form.get('field').markAsTouched(); ничего не делает.

Третья проблема заключается в том, что;даже если вы заставляете ControlValueAccessor работать, удаляя @Input formControl из InputComponent и взаимодействовать с html-вводом без ngModel;тем не менее, mat-form-field не сможет взаимодействовать (т.е. получать статус ошибки) с базовым элементом input, поскольку требуется реализовать MatFormFieldControl

Четвертая проблема заключается в том, что при использовании ReactiveForms,проверки (например, необходимые в вашем случае) и отключенное состояние должны обрабатываться через FormControl неявным образом.

Хорошая новость заключается в том, что у всех этих проблем есть очень простое решение, которое без реализации ControlValueAccessor просто передает formControl в InputComponent.и привязать его к вводу html.

Вот рабочий пример;https://stackblitz.com/edit/angular-fwdrv9

Надеюсь, это поможет, хорошего дня.

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