首页 > web前端 > js教程 > 正文

angular4实现tab栏切换的方法分享

小云云
发布: 2018-01-04 13:03:25
原创
2271人浏览过

本文主要介绍了angular4实现tab栏切换的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。

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

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

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

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

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

复制代码 代码如下:


<router-outlet name="main-content" (activate)="activate($event)" (deactivate)='onDeactivate($event)' ></router-outlet>

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

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

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

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

Angular路由复用策略

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

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

SimpleReuseStrategy.ts代码如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

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

  }

}

登录后复制

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

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数据路由代码如下:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

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


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<p class="row">

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

 </p>

 <p class="col-md-8">

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

  </p>

  <router-outlet></router-outlet>

 </p>

</p>

登录后复制

 整体效果如下:

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

相关推荐:

如何实现tab栏的切换效果

DOM中实现tab栏的切换效果

php实现读写tab分割的文件

以上就是angular4实现tab栏切换的方法分享的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号