Angular视图相关

789 阅读1分钟

ElementRef

// html 
<p #p>some text</p>
// js
@ViewChild('p') pRef: ElementRef

可通过pRef.nativeElement拿到原生节点

TemplateRef

// html
<ng-template #container>some text</ng-template>
// js
@ViewChild('container') conRef: TemplateRef

未渲染前以注释节点占位

ViewContainerRef

// html
<div #div>some text</div>
// js
@ViewChild('div', {read: ViewContainerRef}) divVcRef: ViewContainerRef;

可以将其理解为一块视图容器,通过下面两种方法可以往视图中添加DOM

  1. CreateEmbeddedView,入参类型TemplateRef
  2. CreateComponent, 入参类型ComponentFactory

默认行为===appendChild,修改index可改变插入位置

生成factory:

import { ComponentFactoryResolver } from '@angular/core'
import { ComponentA } from 'xxx'
...

insert() {
    const factory = this.comFR.resolveComponentFactory(ComponentA)
    this.divVcRef.createComponent(factory)
}

ComponentRef

由Factory生成的组件引用,常见的应用是创建Modal

const factory = this.cfr.resolveComponentFactory(ComfirmModalComponent);
const componentRef = factory.create(this.injector)
this.instanceRef = componentRef;
componentRef.instance.isShow = true;
this.appRef.attachView(componentRef.hostView);
document.body.appendChild( (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0])

内容投影

与Vue的Slot类似,可插入DOM or Component,支持多插槽

// ChildComponent
<div class="panel panel-primary">
  <div class="panel-heading">
      <ng-content select="h3"></ng-content>
  </div>
  <div class="panel-body">
      <ng-content select="child2"></ng-content>
  </div>
  <div class="panel-footer">
      <ng-content select="p"></ng-content>
  </div>
</div>

// ParentComponent
<child>
    <h3>这是父层投影进来的内容</h3>
    <child (sayhello)="doSomething()"></child>
    <p>这是底部内容</p>
</child>

控制投影进来的组件

@ContentChild(Child2) child2Com: Child2Component