如何以最有效的方式提取ViewContainerRef和ComponentRef?

时间:2017-07-12 17:54:40

标签: angular angular2-directives angular-material2

我使用angular-material mdSidenav并希望以编程方式打开它并插入自定义组件。

我使用@ViewChild('varName')提取componentInstance和@ViewChild('varName', {read: ViewContainerRef})来提取我放置内容的容器。

所以,我的问题是 - 是否可能只有1个@ViewChild并从提取的参考中获取其他信息。

第二个问题 - 哪些值允许读取属性? ElementRef / ViewContainerRef / ...?

更新

我发现,mdSidenav的ViewContainerRef是我组件的错误容器。如何将component.hostView放在mdSidenav hostView?

1 个答案:

答案 0 :(得分:3)

  

是否可以只有1个@ViewChild并从提取中获取其他信息   参考

不,您无法为一个属性指定多个读取类型。例如,您在html中指定以下内容:

<ng-template mydir #vc></ng-template>

现在可以将其视为ElementRefTemplateRefViewContainerRefMyDirectiveInstance。您无法指定多个read类型,因为Angular不知道该节点的返回值。您必须为每个查询属性指定单个read类型。通常你不能从另一种中获得一种类型。虽然两者都是

  

读取属性允许哪些值?   ElementRef / ViewContainerRef / ...?

您可以通过查询获得以下类型:

  • ElementRef
  • TemplateRef
  • ViewContainerRef
  • 提供者(组件/指令实例)

从这个源代码可以看出:

export function getQueryValue(
    view: ViewData, nodeDef: NodeDef, queryValueType: QueryValueType): any {
  if (queryValueType != null) {
    // a match
    let value: any;
    switch (queryValueType) {
      case QueryValueType.RenderElement:
        value = asElementData(view, nodeDef.index).renderElement;
        break;
      case QueryValueType.ElementRef:
        value = new ElementRef(asElementData(view, nodeDef.index).renderElement);
        break;
      case QueryValueType.TemplateRef:
        value = asElementData(view, nodeDef.index).template;
        break;
      case QueryValueType.ViewContainerRef:
        value = asElementData(view, nodeDef.index).viewContainer;
        break;
      case QueryValueType.Provider:
        value = asProviderData(view, nodeDef.index).instance;
        break;
    }
    return value;
  }
}

RenderElement指向与视图节点关联的本机DOM元素,但它在内部使用,并且无法使用组件中的查询访问AFAIK。