在使用angular進行開發的時候,通過屬性綁定向元件内部傳值的方式,有時候并不能完全滿足需求,比如我們寫了一個公共元件,但是某個模闆使用這個公共元件的時候,需要在其内部添加一些标簽内容,這種情況下,除了使用
ngIf
/
ngSwitch
預先在元件内部定義之外,就可以利用
ngTemplateOutlet
指令向元件傳入内容.
ngTemplateOutlet
指令類似于angularjs中的
ng-transclude
,vuejs中的
slot
.
ngTemplateOutlet
是結構型指令,需要綁定一個
TemplateRef
類型的執行個體.
使用方式如下:
@Component({
selector: 'app',
template: `
<h1>Angular's template outlet and lifecycle example</h1>
<app-content [templateRef]="nestedComponentRef"></app-content>
<ng-template #nestedComponentRef let-name>
<span>Hello {{name}}!</span>
<app-nested-component></app-nested-component>
</ng-template>
`,
})
export class App {}
@Component({
selector: 'app-content',
template: `
<button (click)="display = !display">Toggle content</button>
<template
*ngIf="display"
*ngTemplateOutlet="templateRef context: myContext">
</template>
`,
})
export class Content {
display = false;
@Input() templateRef: TemplateRef;
myContext = {$implicit: 'World', localSk: 'Svet'};
}
@Component({
selector: 'app-nested-component',
template: `
<b>Hello World!</b>
`,
})
export class NestedComponent implements OnDestroy, OnInit {
ngOnInit() {
alert('app-nested-component initialized!');
}
ngOnDestroy() {
alert('app-nested-component destroyed!');
}
}
代碼中除了根元件外定義了兩個元件
- 容器元件:
app-content
- 傳遞進去的内容元件:
app-nested-component
app-content
元件接收一個
TemplateRef
類型的輸入屬性
templateRef
,并在模闆中将其綁定到了
ngTemplateOutlet
指令,當元件接收到
templateRef
屬性時,就會将其渲染到
ngTemplateOutlet
指令所在的位置.
上例中,
app-content
元件
templateRef
屬性的來源,是在根元件的模闆内,直接通過
#
符号擷取到了
app-nested-component
元件所在
<ng-template>
的引用并傳入的.
在實際應用中,除了這種方式,也可以直接在元件内部擷取
TemplateRef
類型的屬性并綁定到
ngTemplateOutlet
指令.
比如在容器元件為模态框的情況下,并不能通過模闆傳值,就可以使用下面這種方式:
@ViewChild('temp') temp: TemplateRef<any>
openDialog(){
this.dialog.open(ViewDialogComponent, {data: this.temp)
}
在容器元件中還可以定義被傳遞内容的上下文(上例
app-content
元件中的
myContext
屬性),其中的
$implicit
屬性作為預設值,在被傳遞的内容中可以以重命名的方式通路(上例
let-name
),對于上下文中其他的屬性,就需要通過
let-屬性名
的方式通路了.