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', '首页');}//关闭一个tabcloseTab({ 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到新加的tabthis.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就可以看不同的数据。同时已经加载的也不会重复加载