人在老家 發表於 2019-6-11 14:45:00

Angular TemplateRef

<p><span style="color: rgba(51, 102, 255, 1); font-size: 16px"><strong>H5之template元素</strong></span></p>
<p><span style="color: rgba(51, 102, 255, 1); font-size: 16px"><strong>  </strong><span style="color: rgba(0, 0, 0, 1); font-size: 14px">模版元素是&nbsp;Web Components 技术中的一种。</span></span></p>
<p><span style="color: rgba(51, 102, 255, 1); font-size: 16px"><span style="color: rgba(0, 0, 0, 1); font-size: 14px">   里面的元素在页面加载时不会呈现,在随后的JS实例化时可以呈现。</span></span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">template </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="tpl"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
   <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>so good <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">template</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">div </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="container"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">div</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">script </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="text/javascript"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">
    const container </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> document.getElementById(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">container</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
    const tpl </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> document.getElementById(</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">tpl</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">'</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
    let tplNode </span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">=</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)"> document.importNode(tpl.content,</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 255, 1)">true</span><span style="background-color: rgba(245, 245, 245, 1); color: rgba(0, 0, 0, 1)">);
    container.appendChild(tplNode);
</span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">script</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>  &nbsp; &nbsp;template 的类型是&nbsp;HTMLTemplateElement.</p>
<p>  &nbsp; &nbsp;模版元素 在 HTMLTemplateElement.content 中, 类型是&nbsp;DocumentFragment,在浏览器渲染出来的结果如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">template </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="tpl"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><strong><span style="color: rgba(255, 0, 0, 1)">
    #document-fragment
    </span></strong><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>so good <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">template</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
</div>
<p>  &nbsp; &nbsp; &nbsp; DocumentFragment 表示一个没有父级文件的最小文档对象,常常被作为一个轻量版的Document使用。</p>
<p>    是DOM节点, 不是真实DOM树的一部分。 在DOM树中,文档片段被其所有子元素代替。</p>
<p>  &nbsp; &nbsp; &nbsp; 因为文档片段存在内存中,不存在DOM树中,将元素插入文档片段时,不会引起回流。</p>
<p>&nbsp;</p>
<p><span style="color: rgba(0, 0, 255, 1); font-size: 16px"><strong>Angular 之 视图类型</strong></span></p>
<p>    Angular 支持的 View 视图 类型:</p>
<p>    1、Embeded Views - Template 模版元素</p>
<p>    2、Host View是 --Componet 组件</p>
<p>&nbsp;</p>
<p><span style="font-size: 16px; color: rgba(0, 0, 255, 1)"><strong>Angular 之 TemplateRef </strong></span>   </p>
<p>  内嵌template模板元素,通过TemplateRef实例,可以通过ElementRef 封装后的nativeElement。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">ng-template </span><span style="color: rgba(255, 0, 0, 1)">#tpl</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>I am span in template {{title}}<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">ng-template</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">

@ViewChild('tpl')
tpl: TemplateRef</span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">any</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">;

title:string = 'jack';

ngAfterViewInit() {
    const embeddedView = this.tpl.createEmbeddedView(null); <span style="color: rgba(0, 128, 0, 1)">// <span style="font-size: 14px">创建内嵌视图</span></span>

    const commentElement = this.tpl.elementRef.nativeElement; <span style="color: rgba(0, 128, 0, 1)">// <span style="font-size: 14px">模版DOM元素,此时被渲染成了 comment元素</span></span>
<br>  <span style="color: rgba(0, 128, 0, 1)">// <span style="font-size: 14px">遍历内嵌视图中的rootNodes, 动态插入 node </span></span>
    embeddedView.rootNodes.forEach( (node) =&gt; {
      commentElement.parentNode.insertBefore(node, commentElement.nextSibling);
    });
}</span></pre>
</div>
<p> &nbsp; &nbsp;<img src="https://img2018.cnblogs.com/blog/338235/201906/338235-20190606142036768-634274930.png" alt="" width="554" height="249"></p>
<p>  &nbsp; <img src="https://img2018.cnblogs.com/blog/338235/201906/338235-20190606144628608-1772071606.png" alt="" width="485"></p>
<p>  由上图可得知如下结论:</p>
<p>    1、&lt;ng-template&gt;元素渲染后被替换成 comment元素。</p>
<p>    2、通过@ViewChild获取的模版元素 this.tpl,是 TemplateRef_ 类的实例。</p>
<p>    &nbsp; &nbsp; 其中 TemplateRef_&lt;C&gt;&nbsp; extends&nbsp; TemplateRef&lt;C&gt; 。</p>
<p>  &nbsp; &nbsp; &nbsp;3、内嵌视图 是 ViewRef_ 对象,其rootNodes属性包含了&lt;template&gt;模版中的内容。</p>
<p>   &nbsp; 4、EmbeddedViewRef&lt;C&gt; extends ViewRef 。</p>
<p>&nbsp;</p>
<p><span style="color: rgba(0, 0, 255, 1)"><strong><span style="font-size: 16px">Angular 之 ViewContainerRef</span></strong></span></p>
<p> <span style="font-size: 14px">   上述方法渲染数据,似乎只能渲染静态文本,而 {{title}} 值却没有渲染出来。</span></p>
<p><span style="font-size: 14px">    这时候就需要 ViewContainerRef。</span></p>
<p><span style="font-size: 14px">    ViewContainerRef: 视图容器,用于创建和管理内嵌视图或组件视图。</span></p>
<p><span style="font-size: 14px">             &nbsp; 可添加一个或多个</span>基于TemplateRef实例创建内嵌视图,指定内嵌视图的插入位置。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">ng-template </span><span style="color: rgba(255, 0, 0, 1)">#tpl1</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>我是第一个模版<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">ng-template</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">ng-template </span><span style="color: rgba(255, 0, 0, 1)">#tpl2</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>我是第二个模版<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">span</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">ng-template</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">

@ViewChild('tpl1')
tpl1: ElementRef</span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">any</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">;

@ViewChild('tpl2')
tpl2: ElementRef</span><span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">any</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">;

@ViewChild('tpl1', { read: ViewContainerRef } )
tplContainer: ViewContainerRef;

ngAfterViewInit() {
   const view1 = this.tpl1.createEmbeddedView(null);
   const view2 = this.tpl2.createEmbeddedView(null);
   this.tplContainer.insert(view1);
   this.tplContainer.insert(view2);
}</span></pre>
</div>
<p>&nbsp;</p>
<p>      </p><br><br>
来源:https://www.cnblogs.com/xianrongbin/p/9686389.html
頁: [1]
查看完整版本: Angular TemplateRef