解析視圖:
-
內嵌視圖- 連接到模板的嵌入視圖,在組件模板元素中添加模板(DOM元素、DOM元素組) -
宿主視圖- 連接到組件的嵌入視圖,在組件元素中添加別的組件
使用類說明:
-
ElementRef- 單個HTML元素;用於獲取DOM元素; -
TemplateRef- 一組HTML元素;可以用來創建ViewRef類型的視圖(TemplateRef元素實例.createEmbeddedView(null)😉,也可以作為TemplateRef對象插入到ViewContainerRef實例中; -
ViewContainerRef- 視圖容器,任何DOM元素都可以作為視圖容器使用; 它可以用來創建和管理內嵌視圖;
創建視圖:
1. 創建內嵌視圖
- HTML - parent.component.html
<!-- 視圖插入的位置 -->
<ng-container #tempContainer></ng-container>
<!-- 視圖模板 -->
<ng-template #tempElem>
<h1>TempElem-title</h1>
<p>TempElem-intro</p>
</ng-template>
- TS - parent.component.ts
export class ParentComponent implements AfterViewInit {
constructor() {
}
@ViewChild('tempContainer', {read: ViewContainerRef})
private tempContainer: ViewContainerRef;
@ViewChild('tempElem')
private tempElem: TemplateRef<any>;
ngAfterViewInit() {
// 創建內嵌視圖 - 以下任意一種方法都可以
this.tempContainer.insert(this.tempElem.createEmbeddedView(null));
// this.tempContainer.createEmbeddedView(this.tempElem);
}
}
-
效果如下:

-
說明:
-
在 Angular 中,我們可以通過 ViewChild 裝飾器來獲取視圖中定義的模板元素,然后利用
ViewContainerRef對象的 createEmbeddedView() /insert()方法,創建內嵌視圖。 -
ViewContainerRef對象的insert方法需要一個ViewRef類型的視圖
-
viewContainerRef實例.createEmbeddedView(TemplateRef實例);;viewContainerRef實例(ViewRef實例)
2. 創建宿主視圖
第一步: 創建動態組件,並且在組件所在模塊的declarations和entryComponents中聲明組件;
import {HomeComponent} from './home.component';
import {ListComponent} from './list.component';
import {DetailComponent} from './detail.component';
const declare = [
HomeComponent,
ListComponent,
DetailComponent
];
@NgModule({
declarations: [...declare],
entryComponents: [...declare]
})
第二步: 定義創建動態組件所需的內容
- HTML
// 組件切換鏈接
<a href="javascript:;" (click)="load('home')">home</a>
<a href="javascript:;" (click)="load('list')">list</a>
<a href="javascript:;" (click)="load('detail')">detail</a>
// 動態組件容器
<div #dynamic></div>
- TS
import {HomeComponent} from './home.component';
import {ListComponent} from './list.component';
import {DetailComponent} from './detail.component';
export class BackendComponent implements OnInit {
// 定義動態組件對象
cmpData = {'home': HomeComponent, 'list': ListComponent, 'detail': DetailComponent};
// 定義動態組件容器
@ViewChild('dynamic', { read: ViewContainerRef }) dmRoom: ViewContainerRef;
constructor(private cfr: ComponentFactoryResolver ) { }
ngOnInit() {
// 默認加載的動態組件
this.loadComponent(this.cmpData['home']);
}
// 定義動態切換組件方法
loadComponent(comName): void { // 動態加載組件
const com = this.cfr.resolveComponentFactory(comName);
this.dmRoom.clear(); // 清空視圖
this.currentCmp = this.dmRoom.createComponent(com);
}
// 定義點擊事件方法
load(name: string) {
this.loadComponent(this.cmpData[name]);
}
}
