首页 文章

Angular - 指令如何“看到”模板和ViewContainer?

提问于
浏览
1

我有一个简单的组件,它通过名为 *appDelay 的自定义指令在延迟后注入数字

我已经知道 * 是一个暗示Angular将语法去糖化的东西

<ng-template ...>
...actual markup
</ng-template>

我也知道我们可以通过以下方式将组件/模板注入 viewContainer

this.viewContainerRef.createEmbeddedView/Component(this.templateRef);

指令代码是:

@Directive({
  selector: '[appDelay]'
})
export class DelayDirective {
  constructor(
    private templateRef: TemplateRef<any>,private viewContainerRef: ViewContainerRef
  ) {  }

  @Input() set appDelay(time: number): void {
    setTimeout(()=>{
      this.viewContainerRef.createEmbeddedView(this.templateRef);
    }, time);
  }
}

文件指出:

要访问Element的ViewContainerRef,您可以在Element上放置使用ViewContainerRef注入的Directive,也可以通过ViewChild查询获取 .

Question:

在一般的伪形式中: templateRefviewContainerRef 的模板"string values"是什么?

恕我直言,脱糖模板将是这样的:

<ng-tempalte ...>
   <card *appDelay="500 * item">
        {{item}}
   </card>
</ng-template>

所以 ViewContainerRef 会引用 <ng-tempalte ...>

而templateRef将是对 <card >...</card> 的引用

  • 那是对的吗 ?

(另外,是否有可能 console.log() 那些HTML模板并看到实际的标记?

https://plnkr.co/edit/80AGn8bR4CiyH0ceP8ws?p=preview

1 回答

  • 2

    ViewContainerRef 只指向将作为插入视图的主机的元素 . 这些视图将作为兄弟姐妹添加到此主机元素中 .

    对于像 <!----> 这样的结构指令注释将是主机元素 .

    Desugar

    <div *appDelay="500">
        Hooray
    </div>
    

    将会

    <ng-template [appDelay]="500">
        <div>
            Hooray
        </div>
    </ng-template>
    

    它也可以这样描述:

    <ng-template view-container-ref></ng-template>
    <!-- ViewRef -->
      <div>
        Hooray
      </div>
    <!-- /ViewRef -->
    

    由于 ng-template 未标记为DOM,因此它将呈现为 <!----> .

    Angular将参考此注释标记创建 ViewContainerRef .

    vcRef.element.nativeElement
    

    每个ViewContainer只能有一个锚元素,每个锚元素只能有一个ViewContainer . ViewContainer是一个帮助您操作视图的容器( ViewRefEmbeddedViewRef

    此外,还将创建 TemplateRef 实例

    class TemplateRef_ {
      constructor(private _parentView: ViewData, private _def: NodeDef) { }
    
      get elementRef(): ElementRef {
        return new ElementRef(asElementData(this._parentView, this._def.index).renderElement);
      }
    

    它的 elementRef (锚点或位置)将指向相同的注释元素 .

    TemplateRef的主要功能是具有 template 属性

    this.templateRef._def.element.template
    

    此属性不包含html字符串,但描述 view

    this.templateRef._def.element.template.factory + ''
    

    将打印

    "function View_AppComponent_1(_l) {
      return jit_viewDef1(0,[(_l()(),jit_elementDef2(0,null,null,1,'div',[],null,null,
          null,null,null)),(_l()(),jit_textDef3(null,['\n    Hooray\n']))],null,null);
    }"
    

    所以这是我们的模板 . 正如您所看到的,它描述了带有 div 根元素的视图和带有文本 \n Hooray\n 的子文本节点

    Angular使用 ViewDefinitions 这些位于 ngfactories 中来构建DOM树
    enter image description here

    也可以看看

    别忘了看https://www.youtube.com/watch?v=EMjTp12VbQ8

相关问题