angular4实现tab栏切换的方法示例
程序员文章站
2022-03-07 10:39:36
管理系统 tab 切换页,是一种常见的需求,大概如下:
点击左边菜单,右边显示相应的选项卡,然后不同的选项卡面可以同时编辑,切换时信息不掉失!
用php或.net,...
管理系统 tab 切换页,是一种常见的需求,大概如下:
点击左边菜单,右边显示相应的选项卡,然后不同的选项卡面可以同时编辑,切换时信息不掉失!
用php或.net,java的开发技术,大概是切换显示,然后加一个ifram来做到,或者通过ajax加载信息显示相应的层.
但是如果用angular 要如何实现呢?第一个想法,是否可以用同样的ifarm来实现呢?
第二个想到的是路由插座大概是这样的
复制代码 代码如下:
<router-outlet name="main-content" (activate)="activate($event)" (deactivate)='ondeactivate($event)' ></router-outlet>
但都没能实现,于是在想一个简单的tab页面就这么难吗?
或者真的没有什么简单的方法了吗?
很长一段时间,没有去管这个了
因为我知道自己对angular的理解和学习还不够,于是就放下了很长一段时间,直到在知乎看到一篇文章
于是有了一种思路,花了半天的时间终于实现了anguar 4 tab 切换页大概思路实现如下:
一、实现 routereusestrategy 接口自定义一个路由利用策略
simplereusestrategy.ts代码如下:
import { routereusestrategy, defaulturlserializer, activatedroutesnapshot, detachedroutehandle } from '@angular/router'; export class simplereusestrategy implements routereusestrategy { public static handlers: { [key: string]: detachedroutehandle } = {} /** 表示对所有路由允许复用 如果你有路由不想利用可以在这加一些业务逻辑判断 */ public shoulddetach(route: activatedroutesnapshot): boolean { return true; } /** 当路由离开时会触发。按path作为key存储路由快照&组件当前实例对象 */ public store(route: activatedroutesnapshot, handle: detachedroutehandle): void { simplereusestrategy.handlers[route.routeconfig.path] = handle } /** 若 path 在缓存中有的都认为允许还原路由 */ public shouldattach(route: activatedroutesnapshot): boolean { return !!route.routeconfig && !!simplereusestrategy.handlers[route.routeconfig.path] } /** 从缓存中获取快照,若无则返回nul */ public retrieve(route: activatedroutesnapshot): detachedroutehandle { if (!route.routeconfig) { return null } return simplereusestrategy.handlers[route.routeconfig.path] } /** 进入路由触发,判断是否同一路由 */ public shouldreuseroute(future: activatedroutesnapshot, curr: activatedroutesnapshot): boolean { return future.routeconfig === curr.routeconfig } }
二、策略注册到模块当中:
import { browsermodule } from '@angular/platform-browser'; import { ngmodule } from '@angular/core'; import { formsmodule } from '@angular/forms'; import { commonmodule as systemcommonmodule } from '@angular/common'; import { appcomponent } from './app.component'; import { approutingmodule,componentlist } from './app.routing' import { simplereusestrategy } from './simplereusestrategy'; import { routereusestrategy } from '@angular/router'; @ngmodule({ declarations: [ appcomponent, componentlist ], imports: [ browsermodule, approutingmodule, formsmodule, systemcommonmodule ], providers: [ { provide: routereusestrategy, useclass: simplereusestrategy } ], bootstrap: [appcomponent] }) export class appmodule { }
上面两步基本上实现了复用策略但要实现第一张效果图,还是要做一些其它工作
三、定义路由添加一些data数据路由代码如下:
import { ngmodule } from '@angular/core'; import { routes, routermodule } from '@angular/router'; import { aboutcomponent } from './home/about.component' import { homecomponent } from './home/home.component' import { newscomponent } from './home/news.component' import { contactcomponent } from './home/contact.component' export const routes: routes = [ { path: '', redirectto: 'home', pathmatch: 'full', }, { path: 'home', component: homecomponent,data: { title: '首页', module: 'home', power: "show" } }, { path: 'news',component: newscomponent ,data: { title: '新闻管理', module: 'news', power: "show" }}, { path: 'contact',component: contactcomponent ,data: { title: '联系我们', module: 'contact', power: "show" }}, { path: 'about', component: aboutcomponent,data: { title: '关于我们', module: 'about', power: "show" } }, ]; @ngmodule({ imports: [routermodule.forroot(routes)], exports: [routermodule] }) export class approutingmodule { } export const componentlist=[ homecomponent, newscomponent, aboutcomponent, contactcomponent ]
四、在<router-outlet></router-outlet> component 实现路由事件 events,app.component代码如下:
import { component } from '@angular/core'; import { simplereusestrategy } from './simplereusestrategy'; import { activatedroute, router, navigationend } from '@angular/router'; import { title } from '@angular/platform-browser'; import 'rxjs/add/operator/filter'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/mergemap'; @component({ selector: 'app-root', styleurls:['app.css'], templateurl: 'app.html', providers: [simplereusestrategy] }) export class appcomponent { //路由列表 menulist: array<{ title: string, module: string, power: string,isselect:boolean }>=[]; constructor(private router: router, private activatedroute: activatedroute, private titleservice: title) { //路由事件 this.router.events.filter(event => event instanceof navigationend) .map(() => this.activatedroute) .map(route => { while (route.firstchild) route = route.firstchild; return route; }) .filter(route => route.outlet === 'primary') .mergemap(route => route.data) .subscribe((event) => { //路由data的标题 let title = event['title']; this.menulist.foreach(p => p.isselect=false); var menu = { title: title, module: event["module"], power: event["power"], isselect:true}; this.titleservice.settitle(title); let exitmenu=this.menulist.find(info=>info.title==title); if(exitmenu){//如果存在不添加,当前表示选中 this.menulist.foreach(p => p.isselect=p.title==title); return ; } this.menulist.push(menu); }); } //关闭选项标签 closeurl(module:string,isselect:boolean){ //当前关闭的是第几个路由 let index=this.menulist.findindex(p=>p.module==module); //如果只有一个不可以关闭 if(this.menulist.length==1) return ; this.menulist=this.menulist.filter(p=>p.module!=module); //删除复用 delete simplereusestrategy.handlers[module]; if(!isselect) return; //显示上一个选中 let menu=this.menulist[index-1]; if(!menu) {//如果上一个没有下一个选中 menu=this.menulist[index+1]; } // console.log(menu); // console.log(this.menulist); this.menulist.foreach(p => p.isselect=p.module==menu.module ); //显示当前路由信息 this.router.navigate(['/'+menu.module]); } } import { component } from '@angular/core'; import { simplereusestrategy } from './simplereusestrategy'; import { activatedroute, router, navigationend } from '@angular/router'; import { title } from '@angular/platform-browser'; import 'rxjs/add/operator/filter'; import 'rxjs/add/operator/map'; import 'rxjs/add/operator/mergemap'; @component({ selector: 'app-root', styleurls:['app.css'], templateurl: 'app.html', providers: [simplereusestrategy] }) export class appcomponent { //路由列表 menulist: array<{ title: string, module: string, power: string,isselect:boolean }>=[]; constructor(private router: router, private activatedroute: activatedroute, private titleservice: title) { //路由事件 this.router.events.filter(event => event instanceof navigationend) .map(() => this.activatedroute) .map(route => { while (route.firstchild) route = route.firstchild; return route; }) .filter(route => route.outlet === 'primary') .mergemap(route => route.data) .subscribe((event) => { //路由data的标题 let title = event['title']; this.menulist.foreach(p => p.isselect=false); var menu = { title: title, module: event["module"], power: event["power"], isselect:true}; this.titleservice.settitle(title); let exitmenu=this.menulist.find(info=>info.title==title); if(exitmenu){//如果存在不添加,当前表示选中 this.menulist.foreach(p => p.isselect=p.title==title); return ; } this.menulist.push(menu); }); } //关闭选项标签 closeurl(module:string,isselect:boolean){ //当前关闭的是第几个路由 let index=this.menulist.findindex(p=>p.module==module); //如果只有一个不可以关闭 if(this.menulist.length==1) return ; this.menulist=this.menulist.filter(p=>p.module!=module); //删除复用 delete simplereusestrategy.handlers[module]; if(!isselect) return; //显示上一个选中 let menu=this.menulist[index-1]; if(!menu) {//如果上一个没有下一个选中 menu=this.menulist[index+1]; } // console.log(menu); // console.log(this.menulist); this.menulist.foreach(p => p.isselect=p.module==menu.module ); //显示当前路由信息 this.router.navigate(['/'+menu.module]); } }
app.html 的代码如下:
<div class="row"> <div class="col-md-4"> <ul> <li><a routerlinkactive="active" routerlink="/home">首页</a></li> <li><a routerlinkactive="active" routerlink="/about">关于我们</a></li> <li><a routerlinkactive="active" routerlink="/news">新闻中心</a></li> <li><a routerlinkactive="active" routerlink="/contact">联系我们</a></li> </ul> </div> <div class="col-md-8"> <div class="crumbs clearfix"> <ul> <ng-container *ngfor="let menu of menulist"> <ng-container *ngif="menu.isselect"> <li class="isselect"> <a routerlink="/{{ menu.module }}">{{ menu.title }}</a> <span (click)="closeurl(menu.module,menu.isselect)">x</span> </li> </ng-container> <ng-container *ngif="!menu.isselect"> <li> <a routerlink="/{{ menu.module }}">{{ menu.title }}</a> <span (click)="closeurl(menu.module,menu.isselect)">x</span> </li> </ng-container> </ng-container> </ul> </div> <router-outlet></router-outlet> </div> </div>
整体效果如下:
最终点击菜单显示相应的标签选中,可以切换编辑内容,关闭标签时,重新点击菜单可以重新加载内容。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。