问题
在模板中显示相应的元素后获得@ViewChild的最优雅的方式是什么?
下面是一个例子。也可提供活塞。
Component.template.html:
<div id="layout" *ngIf="display">
<div #contentPlaceholder></div>
</div>
Component.component.ts:
export class AppComponent {
display = false;
@ViewChild('contentPlaceholder', { read: ViewContainerRef }) viewContainerRef;
show() {
this.display = true;
console.log(this.viewContainerRef); // undefined
setTimeout(() => {
console.log(this.viewContainerRef); // OK
}, 1);
}
}
我有一个默认隐藏其内容的组件。当有人调用show()方法时,它变得可见。然而,在Angular 2变更检测完成之前,我不能引用viewContainerRef。如上所示,我通常将所有必需的操作包装到setTimeout(()=>{},1)中。有没有更正确的方法?
我知道ngAfterViewChecked有一个选项,但它会导致太多无用的调用。
答案(设置)
在我的例子中,我只需要在模板中存在div时加载整个模块,这意味着出口在ngif中。这样,每当angular检测到#geolocalisationOutlet元素时,它就会在其中创建一个组件。该模块也只加载一次。
constructor(
public wlService: WhitelabelService,
public lmService: LeftMenuService,
private loader: NgModuleFactoryLoader,
private injector: Injector
) {
}
@ViewChild('geolocalisationOutlet', {read: ViewContainerRef}) set geolocalisation(geolocalisationOutlet: ViewContainerRef) {
const path = 'src/app/components/engine/sections/geolocalisation/geolocalisation.module#GeolocalisationModule';
this.loader.load(path).then((moduleFactory: NgModuleFactory<any>) => {
const moduleRef = moduleFactory.create(this.injector);
const compFactory = moduleRef.componentFactoryResolver
.resolveComponentFactory(GeolocalisationComponent);
if (geolocalisationOutlet && geolocalisationOutlet.length === 0) {
geolocalisationOutlet.createComponent(compFactory);
}
});
}
<div *ngIf="section === 'geolocalisation'" id="geolocalisation">
<div #geolocalisationOutlet></div>
</div>
在我的例子中,我只需要在模板中存在div时加载整个模块,这意味着出口在ngif中。这样,每当angular检测到#geolocalisationOutlet元素时,它就会在其中创建一个组件。该模块也只加载一次。
constructor(
public wlService: WhitelabelService,
public lmService: LeftMenuService,
private loader: NgModuleFactoryLoader,
private injector: Injector
) {
}
@ViewChild('geolocalisationOutlet', {read: ViewContainerRef}) set geolocalisation(geolocalisationOutlet: ViewContainerRef) {
const path = 'src/app/components/engine/sections/geolocalisation/geolocalisation.module#GeolocalisationModule';
this.loader.load(path).then((moduleFactory: NgModuleFactory<any>) => {
const moduleRef = moduleFactory.create(this.injector);
const compFactory = moduleRef.componentFactoryResolver
.resolveComponentFactory(GeolocalisationComponent);
if (geolocalisationOutlet && geolocalisationOutlet.length === 0) {
geolocalisationOutlet.createComponent(compFactory);
}
});
}
<div *ngIf="section === 'geolocalisation'" id="geolocalisation">
<div #geolocalisationOutlet></div>
</div>