如何在模板中存在ngIf时确定Angular2组件是否已完全加载(包括ViewChilds)

时间:2016-07-12 10:29:41

标签: angular angular-components

当有条件地加载孩子的模板中有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
    }

}

ngOnInit&amp;&amp;由于ngIf条件

,在加载子组件之前触发ngAfterViewInit

我需要在SlideshowComponent&amp; amp; ControlsComponent已加载并根据该行为执行操作。

我有一个hacky解决方案,当有多个ViewChild(不同类型)时不适用 - 使用事件发射器通知孩子何时被加载。

我发布这个问题,因为经过数小时的研究后没有适当的解决方案。

2 个答案:

答案 0 :(得分:1)

PLUNKER

尝试使用ViewChildren代替ViewChildchanges提供changes Observable,我们可以将其用作钩子。

要跟踪所有ViewChildren,您可以将他们的 @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'); }); } } Observable合并为一个并订阅它,然后您获得单一操作点,如下所示

UIImageView * border = [UIImageView new];
border.frame = CGRectMake(0,y,100,0.5f);
border.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.3f];
[self.view addSubview:border];

答案 1 :(得分:1)

您可以将内容包装在* ngIf中,以便html不会显示任何内容,直到ngOnInit全部完成。

<div *ngIf="loaded">
    /* all codes go here */
<div>

OnInit(){
    foo();
    bar(()=>{
        this.loaded = true;
    });
}