当您使用“ @ViewChild”中的信息时,如何避免“ ExpressionChangedAfterItHasBeenCheckedError”或“无法读取未定义的属性”?

塞尔索·阿格拉

我想了解有关@ViewChild及其工作方式的一些问题。我使用的是角度8,由于某种原因,我遇到了一些错误,例如“ ExpressionChangedAfterItHasBeenCheckedError”或“无法读取未定义的属性...”

我试图{static: false}在我的@ViewChild上使用,但是出现了同样的错误。那么,如何解决这个问题及其运作方式呢?

我了解,子组件在显示父组件之后运行。我使用了诸如ngAfterViewInit和AfterViewChecked之类的方法来等待子级信息,但是我遇到了同样的错误。我想念什么吗?

这是我的代码如下:

app-parent.component.ts

@Component({ selector: 'app-parent', templateUrl: './app-parent.component.html' })
export class AppParentComponent implements OnInit, AfterViewChecked {

  @ViewChild('backbtn', {static: false}) backReference : ChildBackComponent;
  previousurl : string = null;

  /*...codes...*/
  ngAfterViewChecked() {
    this.previousurl = this.backReference.previousUrl;
  }
  /*...codes...*/

app-parent.component.html

<!-- HTML codes -->
<app-child-back-button #backbtn >Button</app-child-back-button>
<app-another-child-element *ngIf="currentUrl" [url]="previousurl" ></app-another-child-element>

child-back-button.component.ts

@Component({ selector: "app-child-back-button", templateUrl: "./child-back-button.component.html" })
export class ChildBackComponent implements OnInit {
  public previousUrl: string = "/";

  ngOnInit() {
    this.previousUrl = "/previousurl";
  }

child-back-button.component.html

<a routerLink="{{ previousUrl }}"><ng-content></ng-content></a>

编辑

感谢@ tony-ngo,我解决了这个问题。

只需将我的代码更改为

app-parent.component.ts

@Component({ selector: 'app-parent', templateUrl: './app-parent.component.html' })
export class AppParentComponent implements OnInit, AfterViewInit {

  @ViewChild('backbtn', {static: false}) backReference : ChildBackComponent;
  previousurl : string = null;

  /*...codes...*/
  ngAfterViewInit() {
    setTimeout(() => {
      this.previousurl = this.backReference.previousUrl;
    }, 1000);
  }

  /*...codes...*/

恕我直言,这似乎不是一件容易的事,但它解决了我的问题,并且效果很好。也许您需要等待所有组件变得可用,然后才能从Viewchild获取一些信息。

另一个解决方案似乎更复杂,我必须管理和检测更改,只是为了解决仅在开发模式下发生的问题。因此,第一种解决方案对我来说很好。谢谢!

托尼·恩戈

根据本文,这里有几种修复方法

旁注,因为您试图从视图子级获取最新的更新值,所以需要更新代码

@ViewChild('backbtn', {static: true}) backReference : ChildBackComponent;

使用setTimeout这样的东西

  ngAfterViewChecked() {
    setTimeout(() => {
        this.previousurl = this.backReference.previousUrl;
    }, 1000); // set timeout for 1 second you can change 2000 or 3000
  }

将逻辑移至ngOnInit

ngOnInit() {
    this.previousurl = this.backReference.previousUrl;
  }

像这样使用ChangeDection

@Component({
  changeDetection: ChangeDetectionStrategy.OnPush
})

或者,另一方面,您需要确保让Angular进行更改。首选的方法是使用markForCheck。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档