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方法創(chuàng)建內(nèi)嵌視圖市咽。
this.vcRef.createEmbeddedView(this.tplRef);
} }
這樣其實我們在視圖中就得到了一個什么...啊,就是一個'Big Keriy !'的字符串盏阶。
2. ngTemplateOutlet
指令
a. ngTemplateOutlet
和routerOutlet
是一個意思亮蒋,將視圖(<ng-template>標(biāo)簽中的內(nèi)容)放到對應(yīng)的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 { }
最終的視圖應(yīng)該是:
Big Keriy !
Hello, Semlinker!
b. ngOutletContex
看名字就知道意思懂傀。
ngTemplateOutlet
指令基于TemplateRef
對象,在使用ngTemplateOutlet
指令時蜡感,可以通過ngTemplateOutletContext
屬性來設(shè)置來設(shè)置EmbeddedViewRef
的上下文對象蹬蚁。可以使用let
語法來聲明綁定上下文對象屬性名郑兴。
import { Component, TemplateRef, ViewContainerRef, ViewChild,
AfterViewInit } from '@angular/core';
@Component({
selector: 'app-code404',
template: `
<!-- 這里的messagey映射到下面context中message 再使用插值表達(dá)式的方式顯示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
指令
聽著名字就很爽犀斋,這不是插入視圖的,是插入組件的情连!
該指令使用聲明的方式叽粹,動態(tài)加載組件。
先寫組件却舀,里面有兩個虫几。。組件:
@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;
}
}
當(dāng)然挽拔,還需要在模塊中聲明入口:
// 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. 創(chuàng)建結(jié)構(gòu)指令
也想不出來一個什么好例子辆脸,抄一個例子過來:
// 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;
}
本文部分摘自Semlinker的Angular 4 指令快速入門,感謝作者的分享螃诅。