Angular *ngIf="fg.hasError('email', ['myEmail'])" не работает
Я тестирую некоторую проверку реактивной группы форм, которая включает в себя следующий код: component.ts включает:
fg: FormGroup;
id: string;
obj: MyObj = <MyObj>{};
constructor(
private fb: FormBuilder,
private route: ActivatedRoute,
private store: Store<AppState>
) { }
ngOnInit() {
this.id = this.route.snapshot.paramMap.get('id');
if (this.id) { //edit
this.store.select(selectById(this.id))
.subscribe((obj: MyObj) => {
this.obj = obj;
})
}
this.fg = this.fb.group({
myEmail: [
this.obj.email,
[Validators.email]
]
});
}
component.html включает в себя:
<form [formGroup]="fg" (ngSubmit)="onSubmit()">
<mat-form-field>
<input matInput
type="email"
placeholder="Email"
formControlName="myEmail"
>
<mat-error *ngIf="fg.hasError('email', ['myEmail'])">
Enter a valid email address
</mat-error>
</mat-form-field>
Email HasError: {{ fg.hasError('email', ['myEmail']) }}
</form>
Страница открывается, и она проверяет наличие параметра id, если он есть, то редактирует, а не добавляет, затем находит объект obj, подписавшись на хранилище ngrx и получив объект obj и установив член obj на компоненте.
Определение группы реактивных форм определено так, что myCmail formcontrol получает свое значение из this.obj.email.
Затем существует элемент mat-error, который отображается только в том случае, если элемент управления myEmail недействителен из средства проверки электронной почты.
Теперь проблема в том, что при загрузке формы, если значение адреса электронной почты в магазине недействительно, ошибка остается скрытой до тех пор, пока вы не коснетесь и не покинете поле электронной почты. Тогда ошибка отображается.
Хотя store.select(...). Subcribe() является асинхронным действием, почему значение элемента управления электронной почтой обновляется правильно и {{ ... }} отображается правильно при загрузке. например, 'Email HasError: true'.
Как заставить *ngIf переоценить ошибку fg.hasError, когда она меняется на true? Значит ошибка отображается при загрузке страницы?
Я попытался создать BehaviourSubject на компоненте и вызвать следующий на этом в store.subscribe(). Затем, имея это в *ngIf с асинхронным каналом. Но это тоже не работает.
1 ответ
Вы можете напрямую ссылаться на formControl вашего myEmail на ваш *ngIf, чтобы проверить, является ли ввод действительным или недействительным, или вызвать его из родительской формы (fg).
Добавлен Deckblitz Demo для вашей справки
Method #1
<mat-error *ngIf="myEmail.invalid">
Enter a valid email address
</mat-error>
__________________________________________
Method #2
<mat-error *ngIf="fg.get('myEmail').invalid">
Enter a valid email address
</mat-error>
__________________________________________
Method #3
<mat-error *ngIf="fg.get('myEmail').hasError('email')"> // Can be of 'required', 'pattern', 'minLength' and others
Enter a valid email address
</mat-error>
ОБНОВИТЬ:
ngOnInit() {
this.id = this.route.snapshot.paramMap.get('id');
// Build the form first
this.buildForm();
// If ID is found, fetch/subscribe the store selection
// After that, the fetchStoreSelection will call the initializeFormValues() and set the form fields
if (this.id) this.fetchStoreSelection();
}
buildForm():void {
this.fg = this.fb.group({
myEmail: [ '', [Validators.email] ]
});
}
fetchStoreSelection(): void {
this.store
.select(selectById(this.id))
.subscribe((obj: MyObj) => {
this.obj = obj;
this.initializeFormValues(this.obj); // Once obj is now fetched, call the initializeFormValues() to set it on its form fields
})
}
initializeFormValues(obj):void {
// setValue if you want to set all fields or patchValue if you want to set either one or more fields.
this.fg.setValue({
myEmail: obj.email // set email passed from 'obj' param
});
}