根据属性值选择元素主机

时间:2017-08-03 18:49:09

标签: angular typescript

在我的Angular 4应用程序中,我需要动态创建两个组件并将它们注入模板。我用一个组件成功完成了这个,但现在我需要添加另一个组件。

我有这个指令:

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[component-host]',
})
export class ComponentHost {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

我有这个HTML模板摘录:

<!--- HTML --->
<ng-template component-host></ng-template>

ViewChild

// TypeScript
@ViewChild( ComponentHost ) componentHost: ComponentHost;

这一切都很棒,我有代码创建组件并插入它。但是,现在我需要在同一个模板中动态注入一个额外的组件。目前,我必须分开指令,但这显然不是最佳解决方案。是否可以使用属性值在@ViewChild中选择元素?有点像:

<!--- HTML --->
<ng-template component-host='replace1'></ng-template>
<ng-template component-host='replace2'></ng-template>

// TypeScript
// How do I select the element with an attribute with a certain value?
@ViewChild( ComponentHost ) componentHost: ComponentHost; 

我正在创建这样的组件:

protected createComponent( componentType: Type<any>, componentHost ): any {
  const componentFactory = this.componentFactoryResolver.resolveComponentFactory( componentType );
  const viewContainerRef = componentHost.viewContainerRef;

  viewContainerRef.clear();

  const componentRef = viewContainerRef.createComponent( componentFactory );
  componentRef.changeDetectorRef.detectChanges();

  return componentRef.instance;
}

一旦创建了组件,能够detectChanges()对我来说很重要。我尝试了各种排列但没有效果。有什么想法吗?

如果我使用散列选择器,那么const viewContainerRef = componentHost.viewContainerRef;将返回null。

2 个答案:

答案 0 :(得分:0)

不清楚为什么要使用组件来选择ng-template元素。你可以使用模板参考:

<!--- HTML --->
<ng-template #component-host-replace1></ng-template>
<ng-template #component-host-replace2></ng-template>

// TypeScript
@ViewChild('component-host-replace1', {read: ViewContainerRef}) host1: ViewContainerRef; 
@ViewChild('component-host-replace2', {read: ViewContainerRef}) host2: ViewContainerRef; 

答案 1 :(得分:0)

你试过ViewChildren吗? ViewChild只会给你第一个孩子

https://angular.io/api/core/ViewChildrenDecorator#description