【问题标题】:Error ExpressionChangedAfterItHasBeenCheckedError with child component in AngularAngular中子组件的错​​误ExpressionChangedAfterItHasBeenCheckedError
【发布时间】:2021-11-19 14:20:29
【问题描述】:

我为性别创建了一个子组件。我以我的主要形式使用它。 性别组件的值被加载到这个子组件中,我有一个输入属性来设置选定的值。

export class GenderComponent implements OnInit {
  public errorMessage: string = '';
  @Input() public genders: Gender[];
  @Input() public selectedValue?: string ="";
  @Input() public myForm: FormGroup;

  constructor(private repository: RepositoryService, private controlContainer: ControlContainer,    private errorHandler: ErrorHandlerService, private cd: ChangeDetectorRef) { }

  ngOnInit(): void {
    this.myForm = <FormGroup>this.controlContainer.control;
    this.getGenders();
}
  
  getGenders = () => {
   let apiGender: string = environment.apiAddress + 'Gender'; 
   this.repository.getData(apiGender)
   .subscribe(response => {
   this.genders = response as Gender[];
  },
  (error) => {
    this.errorHandler.handleError(error);
    this.errorMessage = this.errorHandler.errorMessage;
  })
}

  ngAfterViewInit(){
     this.cd.detectChanges();
  }
}

我在主窗体(父级)中这样调用组件:

<app-gender name="gender" id="gender" [formGroup]="myForm" [selectedValue]="user?.gender?.description">
   <em *ngIf="validateControl('gender') && hasError('gender', 'required')">Sélectionnez un genre</em>
</app-gender>

如您所见,我要求对此子组件进行验证。 此主表单旨在更新用户配置文件。因此,我像这样从 Web Api 加载用户配置文件:

public loadUserDetails = () => {
  let id: string = this.activeRoute.snapshot.params['id'];
  let apiUser: string = environment.apiAddress + 'UserAccount' + '/' + id;

  this.repository.getData(apiUser).pipe()
    .subscribe(response => {
      this.user = response as UserAccount;
      this.myForm.patchValue({
      firstname: (<UserAccount>response).firstName,
      lastname: (<UserAccount>response).lastName,
      mail: (<UserAccount>response).mail,
      genderId: (<UserAccount>response).genderId,
      password: (<UserAccount>response).password,
      username: (<UserAccount>response).userName,
      login: (<UserAccount>response).login,
      useraccountTypeId: (<UserAccount>response).useraccountTypeId,
     })
   },
   (error) => {
     this.errorHandler.handleError(error);
     this.errorMessage = this.errorHandler.errorMessage;
   })
 }

我收到以下错误消息:ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it is checked。以前的值:'true'。

我了解问题是由于我在加载用户配置文件值后设置了 genderId。

我找到了几篇关于同一主题的帖子,但我无法将它们改编为我的。

有人可以帮我吗?

谢谢

【问题讨论】:

  • 这个错误最可能的原因是这个 ngIf:*ngIf="validateControl('gender') &amp;&amp; hasError('gender', 'required')" 但是如果没有更多的模板代码就很难判断。如果您可以识别导致它的 ngIf,则调试会更容易。关于这个错误的官方 Angular 视频是调试它的最佳来源:youtube.com/watch?v=O47uUnJjbJc
  • 感谢您的帮助。我已经看过这个视频,但对我来说还不够清楚。
  • 如果可以注释掉模板代码中的 ngIfs,直到找到导致错误的那个,然后发布,这将有助于解决您的问题。
  • 是ngIf喜欢子组件的调用&lt;app-gender name="gender" id="gender" [formGroup]="myForm" [selectedValue]="user?.gender?.description"&gt; &lt;em *ngIf="validateControl('gender') &amp;&amp; hasError('gender', 'required')"&gt;Sélectionnez un genre&lt;/em&gt;&lt;/app-gender&gt;
  • 有人知道表单加载时是否可以取消验证?想法是仅在提交表单时进行验证。

标签: angular


【解决方案1】:

感谢this post,我似乎解决了我的问题。

我将此添加到我的父表单中,并且不再有错误消息。

ngAfterViewChecked(): void {
    this.changeDetectorRef.detectChanges();
}

该类必须实现 AfterViewChecked 并且构造函数需要具有私有只读 changeDetectorRef: ChangeDetectorRef

希望可以帮助其他人。感谢您的帮助。

【讨论】:

    猜你喜欢
    • 2019-02-15
    • 1970-01-01
    • 1970-01-01
    • 2018-07-29
    • 2022-11-22
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 2018-09-17
    相关资源
    最近更新 更多