我有一个模板部分,只有当相应的对象存在时,它才会出现在DOM中。此外,我想获取表单引用,并将fromEvent("更改"(Observable附加到它上
由于数据可能在ngAfterViewInit之后到达,因此不会有要获取的引用。
查看
<div *ngIf="user$ | async">
<form id="form" #form></form>
</div>
组件
@ViewChild('form') form;
ngOnInit(){
this.user$ = this.someService.getUser() // returns Observable<User>
}
ngAfterViewInit(){
const form = document.getElementById('form')
fromEvent(form || this.form,'change')...
}
我也试着把它移到可观察的回调,比如
ngAfterViewInit(){
this.user$ = this.someService.getUser().pipe(map(res => {
const form = document.getElementById('form')
fromEvent(form || this.form,'change')...
return res
}))
}
请不要建议任何涉及setTimeout((的解决方案
在代码中使用
@ViewChild('form') form;
它基本上说"在组件中定义一个实例变量form
,并将其值设置为#form
标识的任何DOM元素
一旦创建了由#form
标识的元素,Angular就会设置实例变量form
的值。
关键是,在你的ngAfterViewInit
中,你说的是
ngAfterViewInit(){
const form = document.getElementById('form')
fromEvent(form || this.form,'change')...
}
它表示您希望使用id为form
的元素的值来设置仅在ngAfterViewInit
方法中可见的变量form
。
当ngAfterViewInit
运行时,该元素可能还不存在,您也不知道它将在何时创建。顺便说一句,您还创建了第二个仅在ngAfterViewInit
中可见的变量form
,以保存this.form
应该保存的内容,即Component实例变量。
您可以考虑的是删除@ViewChild('form') form;
代码和ngAfterViewInit
逻辑,只需在html元素(如(中添加一个事件formChanged
<div *ngIf="user$ | async">
<form id="form" (changed)="formChanged($event)"></form>
</div>
然后实现一个方法formChaged(event)
来做你需要做的任何事情
@Picci的回答是正确的,即对于您发布的代码,您应该简单地在表单标记上使用(更改的(Angular事件,而不是直接挂接到DOM。然而,如果您确实需要像您所说的那样获得对延迟加载组件的引用,则需要执行以下操作:
formInitialised: bool = false;
// Implement AfterViewChecked to run this each time the view
// changes - note this will run many times, so you need to keep
// track of whether you have done whatever form initialisation
// you need.
ngAfterViewChecked() {
// Check if form is now defined
if (this.form && !this.formInitialised) {
// Do whatever you need to do with this.form
this.formInitialised = true;
}
// If the form has disappeared from the page, update
// our flag to say so.
if (!this.form && this.formInitialised) this.formInitialised = false;
}