Angular 动态创建多个页面
场景
最近胡思乱想,感觉网站通过路由切来切去不太好,特别是后台管理台,如果通过只打开一个浏览器页签,打开多个页面,这样就不用浏览器路由切来切去,以tab的形式打开多个页面,如果没有关闭,原来页面的数据就一直在,这样就不需要频繁打开页面,减少了服务器压力,二来好查看数据,于是说干就干。
动态加载组件
根据了解,angular可以通过ng-container动态加载不同的组件,其中ngComponentOutlet传入动态加载的组件名称就可以了
<ng-container *ngComponentOutlet="PageComponent"></ng-container>
通过传入一个组件数组,动态添加需要的组件,然后页面遍历该数组
AdminComponent html 这里的tab使用的是 蚂蚁金服开源的ng-zorro-antd
<nz-tabset [(nzSelectedIndex)]="selectedIndex" nzType="editable-card" [nzHideAdd]="true" (nzClose)="closeTab($event)">
<nz-tab *ngFor="let tab of tabs; let i = index" [nzClosable]="i > 0" [nzTitle]="tab.name">
<ng-container *ngComponentOutlet="tab.pageComponent"></ng-container>
</nz-tab>
</nz-tabset>
AdminComponent ts 其中我们的其他所有的组件都实现CommonComponent,一边传入的参数管理
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../common-share/api/auth/auth.service';
import { NzModalService } from 'ng-zorro-antd/modal';
import { User } from '../common-share/model/user.model';
import { CommonComponent } from './common/common.component';
import { ComponentListService } from './common/componentlist.service';
@Component({
selector: 'app-admin',
templateUrl: './admin.component.html',
styleUrls: ['./admin.component.less']
})
export class AdminComponent implements OnInit {
tabs : Array<{page:string,name:string, pageComponent:CommonComponent}> = [];
//tab现在选择的是第几个
selectedIndex = 0;
constructor(private auth: AuthService,
private modalService :NzModalService,
private componentListService:ComponentListService,) {}
ngOnInit() {
//加载完先添加一个tab 首页
this.newTab('adminIndex', '首页');
}
//关闭一个tab
closeTab({ index }: { index: number }): void {
this.tabs.splice(index, 1);
}
/**
* @param _page 新增tab名称
* @param _name
*/
newTab(_page, _name): void {
//判断存不存在该tab,存在直接切换过去退出
let res :boolean = false;
let checkIndex = 0;
for (let index = 0; index < this.tabs.length; index++) {
const element = this.tabs[index];
if(element.page === _page){
res = true;
checkIndex = index;
break;
}
}
if(res){
this.selectedIndex = checkIndex;
return;
}
//把新加的tab放入tablist中
this.tabs.push({page:_page, name:_name, pageComponent:null});
//切换tab到新加的tab
this.selectedIndex = this.tabs.length;
//得到数组中tab位置
const tabsIndex = this.selectedIndex - 1;
//通过page名称取组件
const oneTab = this.componentListService.getCommonItem(_page);
//给组件赋值
this.tabs[tabsIndex].pageComponent = oneTab.component;
}
}
CommonComponent
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-common',
templateUrl: './common.component.html',
styleUrls: ['./common.component.less']
})
export class CommonComponent {
constructor() { }
}
AccessAnalysisComponent 访问分析实现CommonComponent
import { Component, OnInit } from '@angular/core';
import { CommonComponent } from '../common/common.component';
@Component({
selector: 'app-access-analysis',
templateUrl: './access-analysis.component.html',
styleUrls: ['./access-analysis.component.less']
})
export class AccessAnalysisComponent implements CommonComponent {
constructor() { }
ngOnInit() {
}
}
ComponentListService 里面列举了所有可以加载的组件
import { Injectable } from '@angular/core';
import { CommonItem } from './common.item';
import { ListComponent } from '../todolist/list/list.component';
import { UsersComponent } from '../users/users.component';
import { IndexComponent } from '../index/index.component';
import { AccessAnalysisComponent } from '../access-analysis/access-analysis.component';
import { PushAnalysisComponent } from '../push-analysis/push-analysis.component';
import { AddPushMailComponent } from '../push-mail/add-push-mail/add-push-mail.component';
import { PushMailHistoryComponent } from '../push-mail/push-mail-history/push-mail-history.component';
@Injectable()
export class ComponentListService {
private componentList: Array<{key:string, item:CommonItem}> = [
{
key: "adminIndex", item: new CommonItem(IndexComponent, {})
},{
key: "accessAnalysis", item : new CommonItem(AccessAnalysisComponent, {})
},{
key: "pushAnalysis", item : new CommonItem(PushAnalysisComponent, {})
},{
key: "addPushMail", item : new CommonItem(AddPushMailComponent, {})
},{
key: "pushMailHistory", item : new CommonItem(PushMailHistoryComponent, {})
},{
key: "userList", item : new CommonItem(UsersComponent, {})
},{
key: "todoList", item : new CommonItem(ListComponent, {})
},
];
getComponentList() {
return this.componentList;
}
getCommonItem(_key): CommonItem{
let res = null;
this.componentList.forEach(element => {
if(element.key == _key){
res = element.item;
}
});
return res;
}
}
CommonItem 用来定义组件,封装数据,如果需要的话
import { Type } from '@angular/core';
export class CommonItem {
constructor(public component: Type<any>, public data: any) {}
}
效果图
其中的访问分析和推送分析,原来是选哟通过路由打开不同的页面,现在可以在一个页面,切换tab就可以看不同的数据。同时已经加载的也不会重复加载