angular4实现tab栏切换的方法示例

管理系统 tab 切换页,是一种常见的需求,大概如下:

点击左边菜单,右边显示相应的选项卡,然后不同的选项卡面可以同时编辑,切换时信息不掉失!

用php或.net,java的开发技术,大概是切换显示,然后加一个ifram来做到,或者通过ajax加载信息显示相应的层.

但是如果用angular 要如何实现呢?第一个想法,是否可以用同样的ifarm来实现呢?

第二个想到的是路由插座大概是这样的

代码如下:

但都没能实现,于是在想一个简单的tab页面就这么难吗?

或者真的没有什么简单的方法了吗?

很长一段时间,没有去管这个了

因为我知道自己对angular的理解和学习还不够,于是就放下了很长一段时间,直到在知乎看到一篇文章

于是有了一种思路,花了半天的时间终于实现了anguar 4 tab 切换页大概思路实现如下:

一、实现 RouteReuseStrategy 接口自定义一个路由利用策略

SimpleReuseStrategy.ts代码如下:

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
}
}

二、策略注册到模块当中:

@NgModule({
declarations: [
AppComponent,ComponentList
],imports: [
BrowserModule,AppRoutingModule,FormsModule,SystemCommonModule
],providers: [
{ provide: RouteReuseStrategy,useClass: SimpleReuseStrategy }
],bootstrap: [AppComponent]
})
export class AppModule { }

上面两步基本上实现了复用策略但要实现第一张效果图,还是要做一些其它工作

三、定义路由添加一些data数据路由代码如下:

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',{ path: 'about',component: AboutComponent,data: { title: '关于我们',module: 'about',];

@NgModule({
imports: [RouterModule.forRoot(routes)],exports: [RouterModule]
})

export class AppRoutingModule { }

export const ComponentList=[
HomeComponent,NewsComponent,AboutComponent,ContactComponent
]

四、在 component 实现路由事件 events,app.component代码如下:

@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,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 的代码如下:

整体效果如下:

最终点击菜单显示相应的标签选中,可以切换编辑内容,关闭标签时,重新点击菜单可以重新加载内容。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


kindeditor4.x代码高亮功能默认使用的是prettify插件,prettify是Google提供的一款源代码语法高亮着色器,它提供一种简单的形式来着色HTML页面上的程序代码,实现方式如下: 首先在编辑器里面插入javascript代码: 确定后会在编辑器插入这样的代码: <pre
这一篇我将介绍如何让kindeditor4.x整合SyntaxHighlighter代码高亮,因为SyntaxHighlighter的应用非常广泛,所以将kindeditor默认的prettify替换为SyntaxHighlighter代码高亮插件 上一篇“让kindeditor显示高亮代码”中已经
js如何实现弹出form提交表单?(图文+视频)
js怎么获取复选框选中的值
js如何实现倒计时跳转页面
如何用js控制图片放大缩小
JS怎么获取当前时间戳
JS如何判断对象是否为数组
JS怎么获取图片当前宽高
JS对象如何转为json格式字符串
JS怎么获取图片原始宽高
怎么在click事件中调用多个js函数
js如何往数组中添加新元素
js如何拆分字符串
JS怎么对数组内元素进行求和
JS如何判断屏幕大小
js怎么解析json数据
js如何实时获取浏览器窗口大小
原生JS实现别踩白块小游戏(五)
原生JS实现别踩白块小游戏(一)