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

Roy*_*mir 2 javascript angular

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

我已经知道这*是 Angular 将语法去糖化为类似的提示

<ng-template ...>
...actual markup
</ng-template>
Run Code Online (Sandbox Code Playgroud)

我也知道我们可以将组件/模板注入到viewContainervia :

  this.viewContainerRef.createEmbeddedView/Component(this.templateRef);
Run Code Online (Sandbox Code Playgroud)

指令代码是:

@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);
  }
}
Run Code Online (Sandbox Code Playgroud)

文档指出:

要访问 Element 的 ViewContainerRef,您可以在 Element 上放置一个注入了 ViewContainerRef 的指令,也可以通过 ViewChild 查询获取它。

题:

一般的伪形式中:什么是模板“字符串值”templateRefviewContainerRef

恕我直言,脱糖模板将类似于:

<ng-tempalte ...>
   <card *appDelay="500 * item">
        {{item}}
   </card>
</ng-template>
Run Code Online (Sandbox Code Playgroud)

所以 ViewContainerRef将是对<ng-tempalte ...>

而 templateRef 将是对 <card >...</card>

- 那是对的吗 ?

(另外,是否可以 console.log()这些 HTML 模板并查看实际标记?

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

yur*_*zui 5

ViewContainerRef只需指向将作为插入视图的宿主的元素。这些视图将作为同级添加到此宿主元素。

对于结构指令注释,例如<!---->将是宿主元素。

脱糖

<div *appDelay="500">
    Hooray
</div>
Run Code Online (Sandbox Code Playgroud)

将会

<ng-template [appDelay]="500">
    <div>
        Hooray
    </div>
</ng-template>
Run Code Online (Sandbox Code Playgroud)

它也可以这样描述:

<ng-template view-container-ref></ng-template>
<!-- ViewRef -->
  <div>
    Hooray
  </div>
<!-- /ViewRef -->
Run Code Online (Sandbox Code Playgroud)

由于ng-template没有标记到 DOM,它将被呈现为<!---->.

Angular 将ViewContainerRef参考这个注释标签创建。

vcRef.element.nativeElement
Run Code Online (Sandbox Code Playgroud)

每个 ViewContainer 只能有一个锚元素,每个锚元素只能有一个 ViewContainer。ViewContainer 是一个容器,可以帮助您操作 Views( ViewRef, EmbeddedViewRef)

TemplateRef实例将被创建

class TemplateRef_ {
  constructor(private _parentView: ViewData, private _def: NodeDef) { }

  get elementRef(): ElementRef {
    return new ElementRef(asElementData(this._parentView, this._def.index).renderElement);
  }
Run Code Online (Sandbox Code Playgroud)

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

TemplateRef 的主要特点是拥有template属性

this.templateRef._def.element.template
Run Code Online (Sandbox Code Playgroud)

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

this.templateRef._def.element.template.factory + ''
Run Code Online (Sandbox Code Playgroud)

将打印

"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);
}"
Run Code Online (Sandbox Code Playgroud)

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

Angular 使用ViewDefinitions位于其中的此类ngfactories来构建 DOM 树在此处输入图片说明

也可以看看

不要忘记观看https://www.youtube.com/watch?v=EMjTp12VbQ8