Angular 内嵌视图、宿主视图
解析视图:
-
内嵌视图
- 连接到模板的嵌入视图,在组件模板元素中添加模板(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]);
}
}
https://www.yuque.com/smallwhy?tab=books