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]);
    }     

}

posted @ 2018-10-27 10:01  Zero_追梦  阅读(2047)  评论(0编辑  收藏  举报