javascript - כיצד להשתמש ב-ngIf על input של material ברכיב ילד מבלי לקבל את השגיאה ExpressionChangedAfterItHasBeenCheckedError
הבעיה
יש לי PasswordComponent שאני רוצה להשתמש בו עם ng-template. עם זאת, עכשיו אני מקבל שגיאה ExpressionChangedAfterItHasBeenCheckedError כשאני עורך את הסיסמה. אני רוצה להשתמש ב-errorStateMatcher רק כאשר controlName === 'confirmPassword' ולא הצלחתי להבין דרך אחרת לקשור באופן מותנה את errorMatcher
את כל הקוד ניתן לראות כאן ובתוך password.component.html תמצאו את ng-template שגורם לבעיה:
<template *ngIf="controlName === 'confirmPassword'; then Custom else Default"></template>
<ng-template #Custom>
<input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete" [errorStateMatcher]="errorMatcher"/>
</ng-template>
<ng-template #Default>
<input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete"/>
</ng-template>
הערה: גם אם אתה מסיר את
ng-templateומציב אתngIfישירות עלinput, השגיאה עדיין מופיעה. בתחילה חשבתי שהבעיה היא ב-ng-template, אך למעשה זה ה-ngIf.
השגיאה
המספרים ב-mat-error משתנים ולפעמים הערך הוא aria-describedby: null.
PasswordComponent.html:4 ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'aria-describedby: mat-error-3'. Current value: 'aria-describedby: mat-error-4'.
שלבי שכפול השגיאה
- הזן משהו בשדה הסיסמה
- הקש/לחץ חזרה לשם המשתמש
- הקש/לחץ חזרה לסיסמה
- הקלד או מחק תווים כך שההודעת
mat-errorתשתנה - אתה תראה
ExpressionChangedAfterItHasBeenCheckedErrorבקונסולה.
תשובה #1
נסה את הדברים הבאים:
<input #Custom *ngIf="controlName === 'confirmPassword'; else Default" matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete" [errorStateMatcher]="errorMatcher"/>
<ng-template #Default>
<input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete"/>
</ng-template>
ערוך
בקיצור, זה כנראה נובע מתבנית ילד שמשתמשת בערך של ההורה ששונה לאחר שהתבנית של הילד הוצגה. זה בדרך כלל קורה כאשר הילדים מוצגים לפני שההורה סיים להציג את עצמו. בהתחלה חשבתי שזה נובע מהעובדה שהצבת את ההוראת errorStateMatcher בתבנית ילד.
הסתכל על המאמר הבא מכיוון שהוא מסביר את הבעיה טוב יותר ממה שאני יכול ומכיל גם כמה דפוסים נפוצים שגורמים לבעיה ואיך לשנות אותם כדי לתקן אותה:
https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4
ערוך
בהמשך להערותיך ייתכן שההוראת ngIf מתנגשת עם ההוראת matInput. האם תוכל לנסות את הדברים הבאים:
<ng-container *ngIf="controlName === 'confirmPassword'; else Default">
<input #Custom matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete" [errorStateMatcher]="errorMatcher"/>
</ng-container>
<ng-template #Default>
<input matInput [placeholder]="placeholder" [formControlName]="controlName" [type]="showPassword ? 'text' : 'password'" [autocomplete]="autocomplete"/>
</ng-template>
הדוגמה הבאה היא דוגמה עובדת של זה: דוגמת StackBlitz
