【问题标题】:Angular - How do directives "see" template & ViewContainer?Angular - 指令如何“看到”模板和 ViewContainer?
【发布时间】:2017-10-30 18:30:30
【问题描述】:

我有一个简单的组件,它通过名为 *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);
  }
}

文档说明:

要访问元素的 ViewContainerRef,您可以放置​​一个 在元素上注入 ViewContainerRef 的指令,或者您获得 它通过 ViewChild 查询。

问题:

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

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

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

所以ViewContainerRef 将是对&lt;ng-tempalte ...&gt; 的引用

templateRef 将引用&lt;card &gt;...&lt;/card&gt;

——对吗?

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

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

【问题讨论】:

标签: javascript angular


【解决方案1】:

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

对于像&lt;!----&gt; 这样的结构指令注释将是宿主元素。

脱糖

<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,它将被呈现为&lt;!----&gt;

Angular 将参考这个评论标签创建ViewContainerRef

vcRef.element.nativeElement

每个 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);
  }

它的elementRef(anchor or location) 将指向同一个评论元素。

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 使用位于ngfactoriesViewDefinitions 来构建DOM 树

另见

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

【讨论】:

猜你喜欢
  • 2021-04-24
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-18
  • 1970-01-01
相关资源
最近更新 更多