#angular
Вопрос:
Я получаю компонент, который содержит форму, состоящую из textarea
и а select/option
. Доступные параметры устанавливаются на OnInit
уровне службы, которая получает их с внутреннего сервера. Когда моя форма отображается в первый раз textarea
, отображаются все, но не моя область выбора (см. Рисунок ниже). Чтобы сделать его визуализированным, я должен нажать на один textarea
из них и оставить его. Я заметил, что если я удалю NG_VALUE_ACCESSOR
поставщика, рендеринг будет в порядке, но за счет нарушения моего интерфейса ( ERROR Error: No value accessor for form control with name: 'person'
). У вас есть какие-нибудь идеи ?
Вот мой код:
import { Component, forwardRef, OnDestroy, ChangeDetectionStrategy, OnInit } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormBuilder, FormGroup, Validators, FormControl, NG_VALIDATORS } from '@angular/forms'; import { Subscription } from 'rxjs'; import { FareDTO } from '../../dtos'; import { FareService } from '../../services'; export interface PersonFormValues { lastName: string; firstName: string; address: string; email: string; fare: string; } @Component({ selector: 'app-person-form', templateUrl: './person-form.component.html', styleUrls: ['./person-form.component.css'], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() =gt; PersonFormComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() =gt; PersonFormComponent), multi: true } ], changeDetection: ChangeDetectionStrategy.OnPush }) export class PersonFormComponent implements ControlValueAccessor, OnDestroy, OnInit { form: FormGroup; private _subscriptions: Subscription[] = []; availableFares: FareDTO[] = []; constructor(private formBuilder: FormBuilder, private _fareService: FareService) { } ngOnInit() { this._subscriptions.push( this._fareService.getFares().pipe().subscribe(fares =gt; this.availableFares = fares) ); this.form = this.formBuilder.group({ firstName: ['', Validators.required], lastName: ['', Validators.required], address: [], email: ['', Validators.email], phone: ['', Validators.pattern('[0-9]{10}')], fare: [], }); this._subscriptions.push( this.form.valueChanges.subscribe(value =gt; { this.onChange(value); this.onTouched(); }) ); } ngOnDestroy() { this._subscriptions.forEach(s =gt; s.unsubscribe()); } get value(): PersonFormValues { return this.form.value; } set value(value: PersonFormValues) { this.form.setValue(value); this.onChange(value); this.onTouched(); } onChange(value: PersonFormValues): any { } onTouched(): any { }; writeValue(value: any) { if (value) { this.value = value; } if (value === null) { this.form.reset(); } } get firstNameControl() { return this.form.controls.firstName; } get lastNameControl() { return this.form.controls.lastName; } get emailControl() { return this.form.controls.email; } get phoneControl() { return this.form.controls.phone; } registerOnChange(fn: any) { this.onChange = fn; } registerOnTouched(fn: any) { this.onTouched = fn; } validate(_: FormControl) { return this.form.valid ? null : { profile: { valid: false, }, }; } }
вот мой HTML:
lt;div [formGroup]="form"gt; lt;label for="firstName"gt;First Namelt;/labelgt; lt;input formControlName="firstName" id="firstName" /gt; lt;div *ngIf="firstNameControl.touched amp;amp; firstNameControl.hasError('required')" class="error"gt; first name is required lt;/divgt; lt;label for="lastName"gt;Last Namelt;/labelgt; lt;input formControlName="lastName" id="lastName" /gt; lt;div *ngIf="lastNameControl.touched amp;amp; lastNameControl.hasError('required')" class="error"gt; last name is required lt;/divgt; lt;label for="address"gt;Addresslt;/labelgt; lt;input formControlName="address" type="address" id="address" /gt; lt;label for="email"gt;Emaillt;/labelgt; lt;input formControlName="email" type="email" id="email" /gt; lt;div *ngIf="emailControl.value !== '' amp;amp; emailControl.touched amp;amp; emailControl.invalid" class="error"gt; invalid email lt;/divgt; lt;label for="phone"gt;Phonelt;/labelgt; lt;input formControlName="phone" type="phone" id="phone" /gt; lt;div *ngIf="phoneControl.value !== '' amp;amp; phoneControl.touched amp;amp; phoneControl.invalid" class="error"gt; invalid phone number lt;/divgt; lt;div *ngIf="availableFares.length gt; 0"gt; lt;label for="fare"gt;Farelt;/labelgt; lt;select class="form-select" formControlName="fare"gt; lt;option [value]="fare.name" *ngFor="let fare of availableFares"gt;{{fare.name}}lt;/optiongt; lt;/selectgt; lt;/divgt; lt;/divgt;
Комментарии:
1. Это из-за ОнПуша. Вам необходимо позвонить в службу обнаружения изменений вручную после получения элементов из
this._fareService.getFares()
AsyncPipe или использовать AsyncPipe2. спасибо за подсказку.