本文介绍了angular之ng-template模板加载,分享给大家,具体如下:
html5中的template
template标签的含义:HTML <template>元素是一种用于保存客户端内容的机制,该内容在页面加载时是不可见的,但可以在运行时使用JavaScript进行实例化,可以将一个模板视为正在被存储以供随后在文档中使用的一个内容片段。
属性
此元素仅包含全局属性和只读的 content 属性,通过content 可以读取模板内容,而且可以通过判断 content 属性是否存在来判断浏览器是否支持 <template> 元素。
示例
html
<table id="producttable"> <thead> <tr> <td>UPC_Code</td> <td>Product_Name</td> </tr> </thead> <tbody> <!-- 现有数据可以可选地包括在这里 --> </tbody> </table> <template id="productrow"> <tr> <td class="record"></td> <td></td> </tr> </template>
js
// 通过检查来测试浏览器是否支持HTML模板元素 // 用于保存模板元素的内容属性。 if ('content' in document.createElement('template')) { // 使用现有的HTML tbody实例化表和该行与模板 let t = document.querySelector('#productrow'), td = t.content.querySelectorAll("td"); td[0].textContent = "1235646565"; td[1].textContent = "Stuff"; // 克隆新行并将其插入表中 let tb = document.getElementsByTagName("tbody"); let clone = document.importNode(t.content, true); tb[0].appendChild(clone); // 创建一个新行 td[0].textContent = "0384928528"; td[1].textContent = "Acme Kidney Beans"; // 克隆新行并将其插入表中 let clone2 = document.importNode(t.content, true); tb[0].appendChild(clone2); } else { // 找到另一种方法来添加行到表,因为不支持HTML模板元素。 }
代码运行后,结果将是一个包含(由 JavaScript 生成)两个新行的 HTML 表格:
UPC_Code Product_Name 1235646565 Stuff 0384928528 Acme Kidney Beans
注释掉 tb[0].appendChild(clone);和tb[0].appendChild(clone2);,运行代码,只会看到:
UPC_Code Product_Name
说明template元素中的内容如果不经过处理,浏览器是不会渲染的。
angular中的ng-template
<ng-template>是一个 Angular 元素,它永远不会直接显示出来。在渲染视图之前,Angular 会把<ng-template>及其内容替换为一个注释。
以ngIf为例:
<ng-template> 模板元素与html5的template元素一样,需要被特殊处理后才能渲染。ng主要是通过类TemplateRef和ViewContainerRef实现的。
通过阅读ngIf源码学习如何运用<ng-template>
在使用ngIf 指令时我们并未发现ng-template的身影,这是因为"*"(星号)语法糖的原因,这个简写方法是一个微语法,而不是通常的模板表达式, Angular会解开这个语法糖,变成一个<ng-template>标记,包裹着宿主元素及其子元素。
<div *ngIf="hero" >{{hero.name}}</div>
会被解析为
<ng-template [ngIf]="hero"> <div>{{hero.name}}</div> </ng-template>`
看下ngIf源码
import {Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef} from '@angular/core'; @Directive({selector: '[ngIf]'}) export class NgIf { private _context: NgIfContext = new NgIfContext(); private _thenTemplateRef: TemplateRef<NgIfContext>|null = null; private _elseTemplateRef: TemplateRef<NgIfContext>|null = null; private _thenViewRef: EmbeddedViewRef<NgIfContext>|null = null; private _elseViewRef: EmbeddedViewRef<NgIfContext>|null = null; constructor(private _viewContainer: ViewContainerRef, templateRef: TemplateRef<NgIfContext>) { this._thenTemplateRef = templateRef; } @Input() set ngIf(condition: any) { this._context.$implicit = this._context.ngIf = condition; this._updateView(); } @Input() set ngIfThen(templateRef: TemplateRef<NgIfContext>) { this._thenTemplateRef = templateRef; this._thenViewRef = null; // clear previous view if any. this._updateView(); } @Input() set ngIfElse(templateRef: TemplateRef<NgIfContext>) { this._elseTemplateRef = templateRef; this._elseViewRef = null; // clear previous view if any. this._updateView(); } private _updateView() { if (this._context.$implicit) { if (!this._thenViewRef) { this._viewContainer.clear(); this._elseViewRef = null; if (this._thenTemplateRef) { this._thenViewRef = this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context); } } } else { if (!this._elseViewRef) { this._viewContainer.clear(); this._thenViewRef = null; if (this._elseTemplateRef) { this._elseViewRef = this._viewContainer.createEmbeddedView(this._elseTemplateRef, this._context); } } } } } export class NgIfContext { public $implicit: any = null; public ngIf: any = null; }
ngIf的源码并不难,它的核心就在于_updateView函数,它主要通过ViewContainerRef的createEmbeddedView和clear方法来实现模板TemplateRef的呈现和清除(先不关注当中的then和else等的具体实现)。它使用TemplateRef取得<ng-template>的内容,并通过ViewContainerRef来访问这个视图容器。
TemplateRef
TemplateRef 实例用于表示模板对象,TemplateRef 抽象类的定义如下:
abstract get elementRef(): ElementRef; abstract createEmbeddedView(context: C): EmbeddedViewRef<C>; }
在指令中通过依赖注入TemplateRef可以直接拿到ng-tempalte的TemplateRef,但是在component组件中我们则需要使用viewChild
<ng-template #tptest> <span>template test</span> </ng-template> @ViewChild('tptest') tptest: TemplateRef<any>;
ViewContainerRef
ViewContainerRef 实例提供了 createEmbeddedView() 方法,该方法接收 TemplateRef 对象作为参数,并将模板中的内容作为容器 (comment 元素) 的兄弟元素,插入到页面中。
export abstract class ViewContainerRef { /*基于TemplateRef对象创建Embedded View(内嵌视图),然后根据`index`指定的值,插入到容器中。 如果没有指定`index`的值,新创建的视图将作为容器中的最后一个视图插入。*/ abstract createEmbeddedView<C>( templateRef: TemplateRef<C>, //内嵌视图 context?: C, index?: number): // 创建上下文 EmbeddedViewRef<C>; }
createEmbeddedView:context
创建Template 自身 Context 的属性,以ngFor为例:
查看ngFor Context源码:
export class NgForOfContext<T> { constructor( public $implicit: T, public ngForOf: NgIterable<T>, public index: number, public count: number) {} get first(): boolean { return this.index === 0; } get last(): boolean { return this.index === this.count - 1; } get even(): boolean { return this.index % 2 === 0; } get odd(): boolean { return !this.even; } }
<div *ngFor="let hero of heroes; let i=index; let odd=odd"> ({{i}}) {{hero.name}} </div> 解析后: <ng-template ngFor let-hero [ngForOf]="heroes" let-i="index" let-odd="odd" > <div>({{i}}) {{hero.name}}</div> </ng-template>
从例子中可以看到,通过let-i let-odd可以获取到Template的context,这是angular提供的一种语法。因为在 Angular中是没有作用域继承的,所以在模版中无法隐式实现两个无关数据源。一个简单的实现方案就是:一个显式、一个隐式。由于ng-template tag 是写在某个 Component 的 template属性中的,所以在 ng-template tag 之下的部分当然能访问的也只有 Component 作为 Context 提供的属性,从而保持行为的一致性,而如果需要访问到 Template 的 Context,我们就需要使用额外的引入语法。比如 let-i="index",就是把 Template Context 中的 index属性引入到当前的 Component Context 中并赋予别名 i,这样,我们就能够使用 i 这个标识符来访问到 Template Context 中的属性了,并且仍然保持了行为的一致性和作用域的独立性。
模板输入变量是这样一种变量,你可以在单个实例的模板中引用它的值。 这个例子中有好几个模板输入变量:hero、i和odd。 它们都是用let作为前导关键字。
模板输入变量和模板引用变量是不同的,无论是在语义上还是语法上。
我们使用let关键字(如let hero)在模板中声明一个模板输入变量。 这个变量的范围被限制在所重复模板的单一实例上。
而声明模板引用变量使用的是给变量名加#前缀的方式(#var)。 一个引用变量引用的是它所附着到的元素、组件或指令。它可以在整个模板任意位置**访问。
模板输入变量和引用变量具有各自独立的命名空间。let hero中的hero和#hero中的hero并不是同一个变量。
总结:
<ng-template>在ng中主要通过viewChild TemplateRef ViewContainerRef来实现结构性操作。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
在本章中,我们将研究如何在Joomla中add/install Template 。 添加模板 以下是在Joomla中添加/安装模板的简单步骤。 Step (1) - 单击Extensions → Extension Manager ,如下所示。 Step (2) - 单击Extension Manager ,您将看到以下屏幕。 您可以在此处从Web , package , Directory或U
在模板模式中,抽象类公开定义的方式/模板以执行其方法。 它的子类可以根据需要覆盖方法实现,但调用的方式与抽象类的定义相同。 此模式属于行为模式类别。 实现 (Implementation) 我们将创建一个Game抽象类,定义操作,模板方法设置为final,以便不能覆盖它。 Cricket和Football是扩展Game并覆盖其方法的具体类。 我们的演示类TemplatePatternDemo将使用
说明 调用方法: $.f2e.util.render(temp,data,fn,helper); 函数说明: 调用template渲染模板,依赖于artTemplate库 参数说明: 参数名 类型 说明 备注 temp string html字符串 无 data object 参数名 无 fn function 回调函数 无 helper function artTemplate自定义方法 无
ng-three-template This project was generated with Angular CLI and is designed as a basictemplate for ThreeJS combined with Angularand Bootstrap in Version 4.x The project is setup to use global SCSS o
voidsmarty_function_name(array $params, object &$smarty) All attributes passed to template functions from the template are contained in the$params as an associative array. Either access those values d
在本章中,我们将研究如何在Joomla中create a template 。 创建模板 以下是在Joomla中创建模板的简单步骤 - Step (1) - 在Joomla → Templates文件夹中创建一个名为MyFirstTemplate文件夹。 在MyFirstTemplate文件夹中,再创建2个名为images和CSS的文件夹,以保存所有图像和CSS文件。 Step (2) −在MyF