当模板中有ngIf时如何识别Angular2组件是不是已完全加载(包括ViewChilds)
Posted
技术标签:
【中文标题】当模板中有ngIf时如何识别Angular2组件是不是已完全加载(包括ViewChilds)【英文标题】:How to Identify whether a Angular2 component is completely loaded ( including ViewChilds ) when there is ngIf in template当模板中有ngIf时如何识别Angular2组件是否已完全加载(包括ViewChilds) 【发布时间】:2016-11-14 13:00:56 【问题描述】:当模板中有条件加载子组件的 ngIf 时,是否可以识别 Angular2 组件(此处为 AppComponent)是否已完全加载(包括 ViewChilds )。
参考:Angular 2 @ViewChild annotation returns undefined 此示例取自上述参考资料。感谢kenecaswell
import Component, ViewChild, OnInit, AfterViewInit from 'angular2/core';
import ControlsComponent from './child-component-1';
import SlideshowComponent from './slideshow/slideshow.component';
@Component(
selector: 'app',
template: `
<div *ngIf="controlsOn">
<controls ></controls>
<slideshow></slideshow>
</div>
`,
directives: [SlideshowComponent, ControlsComponent]
)
export class AppComponent
@ViewChild(ControlsComponent) controls:ControlsComponent;
@ViewChild(SlideshowComponent) slide:SlideshowComponent;
controlsOn:boolean = false;
ngOnInit()
console.log('on init', this.controls);
// this returns undefined
ngAfterViewInit()
console.log('on after view init', this.controls);
// this returns null
由于 ngIf 条件,在加载子组件之前触发 ngOnInit && ngAfterViewInit
我需要确定 SlideshowComponent 和 ControlsComponent 何时加载并基于此执行操作。
我有一个 hacky 解决方案,当有多个 ViewChilds 时不适合(它们是不同类型的) - 使用事件发射器通知孩子何时加载。
我发布这个问题是因为经过数小时的研究没有合适的解决方案。
【问题讨论】:
【参考方案1】:您可以将内容包装在 *ngIf 中,这样 html 在 ngOnInit 完成之前不会显示任何内容。
<div *ngIf="loaded">
/* all codes go here */
<div>
OnInit()
foo();
bar(()=>
this.loaded = true;
);
【讨论】:
【参考方案2】:PLUNKER
尝试使用ViewChildren
代替ViewChild
,它提供了一个changes
Observable,我们可以将其用作挂钩。
要跟踪所有 ViewChildren,您可以将他们的 changes
Observables 合并为一个并订阅它,然后您将获得单点操作,就像这样
@ViewChildren(ChildCmp) children: QueryList<ChildCmp>;
@ViewChildren(AnotherChildCmp) anotherChildren: QueryList<ChildCmp>;
childrenDetector: Observable<any>; // merged observable to detect changes in both queries
ngAfterViewInit()
this.childrenDetector = Observable.merge(this.children.changes, this.anotherChildren.changes)
this.childrenDetector.subscribe(() =>
// here you can even check the count of view children, that you queried
// eg: if(this.children.length === 1 && this.anotherChildren.length === 1) bothInitialized();
// or something like that
alert('you just initialized a children');
);
【讨论】:
嗨,我的问题是我有 3 个不同类型的组件 (ViewChild),我想确定何时加载所有三个组件 (ViewChild) 并执行操作。我已经更新了这个问题。谢谢 好的,这个问题是由*ngIf
不让子组件在ViewInit 上初始化引起的,现在ViewChildren
更有意义,因为它可以告诉您子组件何时初始化,参见this PLUNKER
好的,我现在正在尝试,可观察到的更改是否会通知所有更改(角度文档不完整)。
是的,当查询到的组件数量变化时触发
我认为根据github.com/angular/angular/issues/9689,ViewChildren、ContentChildren 更改流在 2.0.0 中已损坏以上是关于当模板中有ngIf时如何识别Angular2组件是不是已完全加载(包括ViewChilds)的主要内容,如果未能解决你的问题,请参考以下文章
Angular 2+ - 当 ngIf 导致隐藏时将 ngModel 设置为 null