管理系統(tǒng) tab 切換頁,是一種常見的需求,大概如下:
公司主營業(yè)務(wù):網(wǎng)站制作、成都網(wǎng)站設(shè)計、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。成都創(chuàng)新互聯(lián)是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴(yán)謹(jǐn)、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)推出萊山免費做網(wǎng)站回饋大家。
點擊左邊菜單,右邊顯示相應(yīng)的選項卡,然后不同的選項卡面可以同時編輯,切換時信息不掉失!
用php或.net,java的開發(fā)技術(shù),大概是切換顯示,然后加一個ifram來做到,或者通過ajax加載信息顯示相應(yīng)的層.
但是如果用angular 要如何實現(xiàn)呢?第一個想法,是否可以用同樣的ifarm來實現(xiàn)呢?
第二個想到的是路由插座大概是這樣的
但都沒能實現(xiàn),于是在想一個簡單的tab頁面就這么難嗎?
或者真的沒有什么簡單的方法了嗎?
很長一段時間,沒有去管這個了
因為我知道自己對angular的理解和學(xué)習(xí)還不夠,于是就放下了很長一段時間,直到在知乎看到一篇文章
Angular路由復(fù)用策略
于是有了一種思路,花了半天的時間終于實現(xiàn)了anguar 4 tab 切換頁大概思路實現(xiàn)如下:
一、實現(xiàn) RouteReuseStrategy 接口自定義一個路由利用策略
SimpleReuseStrategy.ts代碼如下:
import { RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router'; export class SimpleReuseStrategy implements RouteReuseStrategy { public static handlers: { [key: string]: DetachedRouteHandle } = {} /** 表示對所有路由允許復(fù)用 如果你有路由不想利用可以在這加一些業(yè)務(wù)邏輯判斷 */ public shouldDetach(route: ActivatedRouteSnapshot): boolean { return true; } /** 當(dāng)路由離開時會觸發(fā)。按path作為key存儲路由快照&組件當(dāng)前實例對象 */ public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { SimpleReuseStrategy.handlers[route.routeConfig.path] = handle } /** 若 path 在緩存中有的都認(rèn)為允許還原路由 */ 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] } /** 進入路由觸發(fā),判斷是否同一路由 */ public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { return future.routeConfig === curr.routeConfig } }
二、策略注冊到模塊當(dāng)中:
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 { }
上面兩步基本上實現(xiàn)了復(fù)用策略但要實現(xiàn)第一張效果圖,還是要做一些其它工作
三、定義路由添加一些data數(shù)據(jù)路由代碼如下:
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: '聯(lián)系我們', module: 'contact', power: "SHOW" }}, { path: 'about', component: AboutComponent,data: { title: '關(guān)于我們', module: 'about', power: "SHOW" } }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { } export const ComponentList=[ HomeComponent, NewsComponent, AboutComponent, ContactComponent ]
四、在
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的標(biāo)題 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){//如果存在不添加,當(dāng)前表示選中 this.menuList.forEach(p => p.isSelect=p.title==title); return ; } this.menuList.push(menu); }); } //關(guān)閉選項標(biāo)簽 closeUrl(module:string,isSelect:boolean){ //當(dāng)前關(guān)閉的是第幾個路由 let index=this.menuList.findIndex(p=>p.module==module); //如果只有一個不可以關(guān)閉 if(this.menuList.length==1) return ; this.menuList=this.menuList.filter(p=>p.module!=module); //刪除復(fù)用 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 ); //顯示當(dāng)前路由信息 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的標(biāo)題 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){//如果存在不添加,當(dāng)前表示選中 this.menuList.forEach(p => p.isSelect=p.title==title); return ; } this.menuList.push(menu); }); } //關(guān)閉選項標(biāo)簽 closeUrl(module:string,isSelect:boolean){ //當(dāng)前關(guān)閉的是第幾個路由 let index=this.menuList.findIndex(p=>p.module==module); //如果只有一個不可以關(guān)閉 if(this.menuList.length==1) return ; this.menuList=this.menuList.filter(p=>p.module!=module); //刪除復(fù)用 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 ); //顯示當(dāng)前路由信息 this.router.navigate(['/'+menu.module]); } }
app.html 的代碼如下:
整體效果如下:
最終點擊菜單顯示相應(yīng)的標(biāo)簽選中,可以切換編輯內(nèi)容,關(guān)閉標(biāo)簽時,重新點擊菜單可以重新加載內(nèi)容。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。