详解Angular 自定义结构指令
程序员文章站
2022-06-24 17:03:01
1. 元素
import { component, templateref, viewcontainerref, viewc...
1. <ng-template>元素
import { component, templateref, viewcontainerref, viewchild, afterviewinit } from '@angular/core'; @component({ selector: 'app-code404', template: ` <!-- 这里使用一个模板变量,在组件中使用@viewchild装饰器获取模板元素--> <ng-template #tpl> big keriy ! </ng-template> `, }) export class code404component implements afterviewinit{ // @viewchild 装饰器获取模板元素 @viewchild('tpl') tplref: templateref<any>; constructor(private vcref: viewcontainerref) {} ngafterviewinit() { // 使用viewcontainerref对象的createembeddedview方法创建内嵌视图。 this.vcref.createembeddedview(this.tplref); } }
这样其实我们在视图中就得到了一个什么...啊,就是一个'big keriy !'的字符串。
2. ngtemplateoutlet指令
a. ngtemplateoutlet
和routeroutlet是一个意思,将视图(<ng-template>标签中的内容)放到对应的ngtemplateoutlet下面。
import { component } from '@angular/core'; @component({ selector: 'app-code404', template: ` <ng-template #stpl> hello, semlinker! </ng-template> <ng-template #atpl> big keriy ! </ng-template> <div [ngtemplateoutlet]="atpl"></div> <div [ngtemplateoutlet]="stpl"></div> `, }) export class code404component { }
最终的视图应该是:
big keriy !
hello, semlinker!
b. ngoutletcontex
看名字就知道意思。
ngtemplateoutlet指令基于templateref对象,在使用ngtemplateoutlet指令时,可以通过ngtemplateoutletcontext属性来设置来设置embeddedviewref的上下文对象。可以使用let语法来声明绑定上下文对象属性名。
import { component, templateref, viewcontainerref, viewchild, afterviewinit } from '@angular/core'; @component({ selector: 'app-code404', template: ` <!-- 这里的messagey映射到下面context中message 再使用插值表达式的方式显示message的值 --> <ng-template #stpl let-message="message"> <p>{{message}}</p> </ng-template> <!-- 这里的messagey映射到下面context中message , let-msg是一种与语法糖的方式变量名是msg--> <ng-template #atpl let-msg="message"> <p>{{msg}}</p> </ng-template> <!-- 若不指定变量值那么将显示 $implicit 的值--> <ng-template #otpl let-msg> <p>{{msg}}</p> </ng-template> <div [ngtemplateoutlet]="atpl" // 这里ngoutletcontext绑定的是context对象 [ngoutletcontext]="context"> </div> <div [ngtemplateoutlet]="stpl" [ngoutletcontext]="context"> </div> <div [ngtemplateoutlet]="otpl" [ngoutletcontext]="context"> </div> `, }) export class code404component implements afterviewinit{ @viewchild('tpl') tplref: templateref<any>; constructor(private vcref: viewcontainerref) {} ngafterviewinit() { this.vcref.createembeddedview(this.tplref); } context = { message: 'hello ngoutletcontext!', $implicit: 'great, semlinker!' }; // 这里的$implicit是固定写法 }
先看输出的视图:
hello ngoutletcontext!
hello ngoutletcontext!
hello, semlinker!
3. ngcomponentoutlet指令
听着名字就很爽,这不是插入视图的,是插入组件的!
该指令使用声明的方式,动态加载组件。
先写组件,里面有两个。。组件:
@component({ selector: 'alert-success', template: ` <p>alert success</p> `, }) export class alertsuccesscomponent { } @component({ selector: 'alert-danger', template: ` <p>alert danger</p> `, }) export class alertdangercomponent { } @component({ selector: 'my-app', template: ` <h1>angular version 4</h1> <ng-container *ngcomponentoutlet="alert"></ng-container> <button (click)="changecomponent()">change component</button> `, }) export class appcomponent { alert = alertsuccesscomponent; changecomponent() { this.alert = alertdangercomponent; } }
当然,还需要在模块中声明入口:
// app.module.ts @ngmodule({ // ... declarations: [ appcomponent, signupcomponent, alertsuccesscomponent, alertdangercomponent ], entrycomponents: [ // 这里面写指令中呀用到的组件 alertsuccesscomponent, alertdangercomponent ], // ... })
这样就可以使用ngcomponentoutlet指令来插入组件玩耍了:
<!-- 简单语法 --> <ng-container *ngcomponentoutlet="componenttypeexpression"></ng-container> <!-- 完整语法 --> <ng-container *ngcomponentoutlet="componenttypeexpression; injector: injectorexpression; content: contentnodesexpression;"> </ng-container>
这是一个完整语法简单的例子:
// ... @component({ selector: 'ng-component-outlet-complete-example', template: ` <ng-container *ngcomponentoutlet="completecomponent; injector: myinjector; content: mycontent"></ng-container>` }) class ngtemplateoutletcompleteexample { // this field is necessary to expose completecomponent to the template. completecomponent = completecomponent; myinjector: injector; mycontent = [[document.createtextnode('ahoj')], [document.createtextnode('svet')]]; constructor(injector: injector) { this.myinjector = reflectiveinjector.resolveandcreate([greeter], injector); } }
4. 创建结构指令
也想不出来一个什么好例子,抄一个例子过来:
// uless.directive.ts import { directive, input, templateref, viewcontainerref } from '@angular/core'; @directive({ selector: '[exeunless]' }) export class unlessdirective { @input('exeunless') set condition(newcondition: boolean) { // set condition if (!newcondition) { this.viewcontainer.createembeddedview(this.templateref); } else { this.viewcontainer.clear(); } } constructor(private templateref: templateref<any>, private viewcontainer: viewcontainerref) { } } import { component } from '@angular/core'; @component({ selector: 'app-root', template: ` <h2 *exeunless="condition">hello, semlinker!</h2> `, }) export class appcomponent { condition: boolean = false; } // app.component.ts import { component } from '@angular/core'; @component({ selector: 'app-root', template: ` <h2 *exeunless="condition">hello, semlinker!</h2> `, }) export class appcomponent { condition: boolean = false; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
下一篇: Linux系统编程