如何识别当模板中有ngIf时,Angular2组件是否完全加载(包括ViewChilds)



当模板中有 ngIf 有条件地加载子组件时,是否可以识别 Angular2 组件(此处为 AppComponent)是否已完全加载(包括 ViewChilds)。

参考:角度 2 @ViewChild注释返回未定义此示例取自上述参考。感谢肯尼卡斯韦尔

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 在加载子组件之前触发

我需要确定何时加载幻灯片组件和控件组件并基于此执行操作。

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

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

PLUNKER

尝试ViewChildren而不是 ViewChild ,它提供了一个changes可观察的,我们可以用作钩子。

要跟踪所有 ViewChildren,您可以将他们的changes可观察量合并为一个并订阅它,然后您将获得单点操作,如下所示

  @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');
    });
  }
}
你可以用

*ngIf 包装东西,这样 html 就不会显示任何内容,直到 ngOnInit 完成所有内容。

<div *ngIf="loaded">
    /* all codes go here */
<div>
OnInit(){
    foo();
    bar(()=>{
        this.loaded = true;
    });
}

相关内容

最新更新