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 
   });
}
Другие вопросы по тегам