我想了解有关@ViewChild及其工作方式的一些问题。 我使用的是角度8,由于某种原因,我遇到了一些错误,例如“ ExpressionChangedAfterItHaHasBeenCheckedError”或“无法读取未定义的属性...”
我试图在我的@ViewChild上使用{static: false}
,但是遇到了同样的错误。那么,如何解决这个问题及其运作方式呢?
我知道,子组件在显示父组件之后运行。我使用了诸如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获取一些信息。
另一种解决方案似乎更复杂,我必须管理和检测更改,以解决仅在开发模式下发生的问题。因此,第一个解决方案对我来说很好。谢谢!
答案 0 :(得分:1)
基于此article,这里有几种修复方法
旁注,因为您正试图从视图子级获取最新的更新值,所以您需要更新代码
@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。