From ba0683dffe0a40b533f48ef737caad574016246c Mon Sep 17 00:00:00 2001
From: zhouyuejun <505127606@qq.com>
Date: Mon, 3 Dec 2018 11:28:24 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=B7=AF=E7=94=B1=E5=A4=8D?=
=?UTF-8?q?=E7=94=A8=E7=AD=96=E7=95=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/app/app-routing.module.ts | 11 +-
src/app/app.module.ts | 9 +-
src/app/login/login-routing.module.ts | 3 +-
.../basic-data/basic-data-routing.module.ts | 42 +++--
.../historical-data-routing.module.ts | 3 +-
src/app/pages/main/main-routing.module.ts | 3 +-
src/app/pages/main/main.component.html | 12 +-
src/app/pages/main/main.component.scss | 13 ++
src/app/pages/main/main.component.ts | 175 +++++++++---------
src/app/pages/operate-spin-service.service.ts | 4 +-
src/app/pages/pages-routing.module.ts | 15 +-
src/app/pages/pages.component.html | 6 +-
src/app/pages/pages.component.scss | 14 ++
src/app/pages/pages.component.ts | 10 +-
src/app/pages/pages.module.ts | 2 +-
.../seasonal-plan-routing.module.ts | 3 +-
.../system-management-routing.module.ts | 19 +-
src/app/register/register-routing.module.ts | 3 +-
src/app/router-reuse-strategy.ts | 85 +++++++++
src/app/services/websocket.service.ts | 1 +
src/assets/images/page-loading.gif | Bin 0 -> 1324443 bytes
21 files changed, 289 insertions(+), 144 deletions(-)
create mode 100644 src/app/router-reuse-strategy.ts
create mode 100644 src/assets/images/page-loading.gif
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index fad259a..f6284ca 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -6,7 +6,7 @@ import { RouterModule, Routes } from '@angular/router';
import { SelectivePreloadingStrategy } from './preloading-strategy';
/* 引入路由权限控制 */
-import {LoginAuthService} from './services/login-auth.service'
+import { LoginAuthService } from './services/login-auth.service'
/* 定义路由 */
@@ -15,18 +15,19 @@ const appRoutes: Routes = [
{
path: 'login',
loadChildren: './login/login.module#LoginModule',
- canActivate:[LoginAuthService],
+ canActivate: [LoginAuthService],
+ data: { preload: false, reuse: false }
},
{
path: 'register',
loadChildren: './register/register.module#RegisterModule',
- // data: { preload: false }
+ data: { preload: false, reuse: false }
},
{
path: 'app',
loadChildren: './pages/pages.module#PagesModule',
- canActivate:[LoginAuthService],
- data: { preload: false }
+ canActivate: [LoginAuthService],
+ data: { preload: false, reuse: true }
}
]
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 60b74b6..36ff455 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,5 +1,6 @@
import { BrowserModule } from '@angular/platform-browser';
-import { BrowserAnimationsModule } from '@angular/platform-browser/animations'
+import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
+import { RouteReuseStrategy } from '@angular/router';
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'
import { HttpClientModule } from '@angular/common/http'
@@ -25,6 +26,9 @@ import { LoginAuthService } from './services/login-auth.service';
/* websocket */
import { WebsocketService } from './services/websocket.service';
+/* 路由缓存策略 */
+import { AppReuseStrategy } from './router-reuse-strategy';
+
@NgModule({
declarations: [
AppComponent
@@ -43,7 +47,8 @@ import { WebsocketService } from './services/websocket.service';
LoginAuthService,
HttpService,
HttpClientService,
- WebsocketService
+ WebsocketService,
+ { provide: RouteReuseStrategy, useClass: AppReuseStrategy }
],
bootstrap: [AppComponent]
})
diff --git a/src/app/login/login-routing.module.ts b/src/app/login/login-routing.module.ts
index f3c9374..7710a68 100644
--- a/src/app/login/login-routing.module.ts
+++ b/src/app/login/login-routing.module.ts
@@ -6,7 +6,8 @@ import { LoginComponent } from './login.component'
const loginRoutes: Routes = [
{
path: '',
- component: LoginComponent
+ component: LoginComponent,
+ data: { preload: false, reuse: false }
}
]
diff --git a/src/app/pages/basic-data/basic-data-routing.module.ts b/src/app/pages/basic-data/basic-data-routing.module.ts
index eb8ba7a..2d7bf98 100644
--- a/src/app/pages/basic-data/basic-data-routing.module.ts
+++ b/src/app/pages/basic-data/basic-data-routing.module.ts
@@ -21,57 +21,75 @@ const basicDataRoutes: Routes = [
path: '',
component: BasicDataComponent,
children:[
+ {
+ path:'',
+ redirectTo:'chekingroup',
+ pathMatch:'full'
+ },
{
path:'checkingroup',
- component:CheckinGroupComponent
+ component:CheckinGroupComponent,
+ data: { preload: true, reuse: false }
},
{
path:'gate',
- component:GateComponent
+ component:GateComponent,
+ data: { preload: true, reuse: false }
},
{
path:'terminal',
component:TerminalComponent,
+ data: { preload: true, reuse: false }
},
{
path:'chut',
- component:ChutComponent
+ component:ChutComponent,
+ data: { preload: true, reuse: false }
},
{
path:'stand',
- component:StandComponent
+ component:StandComponent,
+ data: { preload: true, reuse: false }
},
{
path:'carousel',
- component:CarouselComponent
+ component:CarouselComponent,
+ data: { preload: true, reuse: false }
},
{
path:'checkindesk',
- component:CheckinDeskComponent
+ component:CheckinDeskComponent,
+ data: { preload: true, reuse: false }
},
{
path:'airport',
- component:AirportComponent
+ component:AirportComponent,
+ data: { preload: true, reuse: false }
},
{
path:'city',
- component:CityComponent
+ component:CityComponent,
+ data: { preload: true, reuse: false }
},
{
path:'aircrafttype',
- component:AircraftTypeComponent
+ component:AircraftTypeComponent,
+ data: { preload: true, reuse: false }
},
{
path:'aircraft',
- component:AircraftComponent
+ component:AircraftComponent,
+ data: { preload: true, reuse: false }
},
{
path:'terminalarea',
- component:TerminalAreaComponent
+ component:TerminalAreaComponent,
+ data: { preload: true, reuse: false }
},
{
path:'airline',
- component:AirlineComponent
+ component:AirlineComponent,
+ data: { preload: true, reuse: false }
}
]
}
diff --git a/src/app/pages/historical-data/historical-data-routing.module.ts b/src/app/pages/historical-data/historical-data-routing.module.ts
index b62e70b..4014ea0 100644
--- a/src/app/pages/historical-data/historical-data-routing.module.ts
+++ b/src/app/pages/historical-data/historical-data-routing.module.ts
@@ -6,7 +6,8 @@ import { HistoricalDataComponent } from './historical-data.component';
const historicalDataRoutes: Routes = [
{
path: '',
- component: HistoricalDataComponent
+ component: HistoricalDataComponent,
+ data: { preload: true, reuse: false }
}
]
diff --git a/src/app/pages/main/main-routing.module.ts b/src/app/pages/main/main-routing.module.ts
index 952014b..1fa5d67 100644
--- a/src/app/pages/main/main-routing.module.ts
+++ b/src/app/pages/main/main-routing.module.ts
@@ -5,7 +5,8 @@ import { MainComponent } from './main.component'
const mainRoutes: Routes = [
{
path: '',
- component: MainComponent
+ component: MainComponent,
+ data: { preload: true, reuse: true }
}
]
diff --git a/src/app/pages/main/main.component.html b/src/app/pages/main/main.component.html
index 5b9bc66..9540874 100644
--- a/src/app/pages/main/main.component.html
+++ b/src/app/pages/main/main.component.html
@@ -18,10 +18,7 @@
-
-
@@ -53,12 +50,6 @@
-
\ No newline at end of file
diff --git a/src/app/pages/pages.component.scss b/src/app/pages/pages.component.scss
index 9a92bbc..095070a 100644
--- a/src/app/pages/pages.component.scss
+++ b/src/app/pages/pages.component.scss
@@ -110,6 +110,7 @@
}
}
.right-wrapper {
+ position: relative;
height: calc(100% - 66px);
margin-left: 235px;
}
@@ -128,3 +129,16 @@
}
}
}
+
+.page-loading{
+ width: 100%;
+ height: 100%;
+ // background-image: url('../../assets/images/page-loading.gif');
+ background-color: rgba(0, 0, 0, 0.5);
+ background-repeat: no-repeat;
+ background-size: 100% 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 999;
+}
\ No newline at end of file
diff --git a/src/app/pages/pages.component.ts b/src/app/pages/pages.component.ts
index 68fcd56..5cbe838 100644
--- a/src/app/pages/pages.component.ts
+++ b/src/app/pages/pages.component.ts
@@ -18,7 +18,7 @@ import { filter } from 'rxjs/operators';
})
export class PagesComponent implements OnInit {
public menuClose: boolean = false;
- public isSpinning: any = false;
+ public isSpinning: any = true;
menuData = [
{
"name": "航班动态",
@@ -192,7 +192,7 @@ export class PagesComponent implements OnInit {
constructor(
private router: Router,
private basicDataService: BasicDataService,
- // private operateSpinService: OperateSpinServiceService,
+ private operateSpinService: OperateSpinServiceService,
private httpClient: HttpClientService,
private toastService: ToastService,
) {
@@ -209,9 +209,9 @@ export class PagesComponent implements OnInit {
this.selectActiveMenu(this.menuData, event['urlAfterRedirects'])
});
- // this.operateSpinService.spinSubject.subscribe(
- // val => this.isSpinning = val
- // )
+ this.operateSpinService.spinSubject.subscribe(
+ val => this.isSpinning = val
+ )
}
diff --git a/src/app/pages/pages.module.ts b/src/app/pages/pages.module.ts
index 3e96edd..b5faecc 100644
--- a/src/app/pages/pages.module.ts
+++ b/src/app/pages/pages.module.ts
@@ -20,6 +20,6 @@ import { OperateSpinServiceService } from './operate-spin-service.service';
PagesRoutingModule,
],
declarations: [PagesComponent],
- providers: [BasicDataService]
+ providers: [BasicDataService, OperateSpinServiceService]
})
export class PagesModule { }
diff --git a/src/app/pages/seasonal-plan/seasonal-plan-routing.module.ts b/src/app/pages/seasonal-plan/seasonal-plan-routing.module.ts
index 060585e..f415337 100644
--- a/src/app/pages/seasonal-plan/seasonal-plan-routing.module.ts
+++ b/src/app/pages/seasonal-plan/seasonal-plan-routing.module.ts
@@ -6,7 +6,8 @@ import { SeasonalPlanComponent } from './seasonal-plan.component';
const seasonalPlanRoutes: Routes = [
{
path: '',
- component: SeasonalPlanComponent
+ component: SeasonalPlanComponent,
+ data: { preload: true, reuse: false }
}
]
diff --git a/src/app/pages/system-management/system-management-routing.module.ts b/src/app/pages/system-management/system-management-routing.module.ts
index f52016b..a0002b7 100644
--- a/src/app/pages/system-management/system-management-routing.module.ts
+++ b/src/app/pages/system-management/system-management-routing.module.ts
@@ -22,31 +22,38 @@ const systemManagementRoutes: Routes = [
},
{
path: 'settings',
- component: PersonalSettingsComponent
+ component: PersonalSettingsComponent,
+ data: { preload: true, reuse: false }
},
{
path: 'roles',
- component: RoleManagementComponent
+ component: RoleManagementComponent,
+ data: { preload: true, reuse: false }
},
{
path: 'users',
component: UserManagementComponent,
+ data: { preload: true, reuse: false }
},
{
path: 'departments',
- component: DepartmentManagementComponent
+ component: DepartmentManagementComponent,
+ data: { preload: true, reuse: false }
},
{
path: 'logs',
- component: OperationLogsComponent
+ component: OperationLogsComponent,
+ data: { preload: true, reuse: false }
},
{
path: 'synchronization',
- component: DataSynchronizeComponent
+ component: DataSynchronizeComponent,
+ data: { preload: true, reuse: false }
},
{
path: 'users/modify',
- component: UserManagementModifyComponent
+ component: UserManagementModifyComponent,
+ data: { preload: true, reuse: false }
}
]
}
diff --git a/src/app/register/register-routing.module.ts b/src/app/register/register-routing.module.ts
index af8b654..d8d289e 100644
--- a/src/app/register/register-routing.module.ts
+++ b/src/app/register/register-routing.module.ts
@@ -6,7 +6,8 @@ import { RegisterComponent } from './register.component'
const registerRoutes: Routes = [
{
path: '',
- component: RegisterComponent
+ component: RegisterComponent,
+ data: { preload: false, reuse: false }
}
]
diff --git a/src/app/router-reuse-strategy.ts b/src/app/router-reuse-strategy.ts
new file mode 100644
index 0000000..32c6b55
--- /dev/null
+++ b/src/app/router-reuse-strategy.ts
@@ -0,0 +1,85 @@
+import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router';
+import { Injectable } from '@angular/core';
+
+interface IRouteConfigData {
+ reuse: boolean;
+}
+
+interface ICachedRoute {
+ handle: DetachedRouteHandle;
+ data: IRouteConfigData;
+}
+@Injectable()
+export class AppReuseStrategy implements RouteReuseStrategy {
+ private routeCache = new Map();
+
+ shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
+ return future.routeConfig === curr.routeConfig;
+ }
+
+ shouldDetach(route: ActivatedRouteSnapshot): boolean {
+ const data = this.getRouteData(route);
+ return data && data.reuse;
+ }
+
+ store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
+ const url = this.getFullRouteUrl(route);
+ const data = this.getRouteData(route);
+ this.routeCache.set(url, { handle, data });
+ this.addRedirectsRecursively(route);
+ }
+
+ shouldAttach(route: ActivatedRouteSnapshot): boolean {
+ const url = this.getFullRouteUrl(route);
+ return this.routeCache.has(url);
+ }
+
+ retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
+ console.log(route)
+ const url = this.getFullRouteUrl(route);
+ const data = this.getRouteData(route);
+ console.log(this.routeCache.get(url));
+ return data && data.reuse && this.routeCache.has(url)
+ ? this.routeCache.get(url).handle
+ : null;
+ }
+
+ private addRedirectsRecursively(route: ActivatedRouteSnapshot): void {
+ const config = route.routeConfig;
+ if (config) {
+ if (!config.loadChildren) {
+ const routeFirstChild = route.firstChild;
+ const routeFirstChildUrl = routeFirstChild
+ ? this.getRouteUrlPaths(routeFirstChild).join('/')
+ : '';
+ const childConfigs = config.children;
+ if (childConfigs) {
+ const childConfigWithRedirect = childConfigs.find(c => c.path === '' && !!c.redirectTo);
+ if (childConfigWithRedirect) {
+ childConfigWithRedirect.redirectTo = routeFirstChildUrl;
+ }
+ }
+ }
+ route.children.forEach(childRoute => this.addRedirectsRecursively(childRoute));
+ }
+ }
+
+ private getFullRouteUrl(route: ActivatedRouteSnapshot): string {
+ return this.getFullRouteUrlPaths(route).filter(Boolean).join('/');
+ }
+
+ private getFullRouteUrlPaths(route: ActivatedRouteSnapshot): string[] {
+ const paths = this.getRouteUrlPaths(route);
+ return route.parent
+ ? [...this.getFullRouteUrlPaths(route.parent), ...paths]
+ : paths;
+ }
+
+ private getRouteUrlPaths(route: ActivatedRouteSnapshot): string[] {
+ return route.url.map(urlSegment => urlSegment.path);
+ }
+
+ private getRouteData(route: ActivatedRouteSnapshot): IRouteConfigData {
+ return route.routeConfig && route.routeConfig.data as IRouteConfigData;
+ }
+}
\ No newline at end of file
diff --git a/src/app/services/websocket.service.ts b/src/app/services/websocket.service.ts
index 3a9dcae..a9123b7 100644
--- a/src/app/services/websocket.service.ts
+++ b/src/app/services/websocket.service.ts
@@ -28,6 +28,7 @@ export class WebsocketService {
ob.error("连接失败")
}
this.websocket.onclose = () => {
+ console.log('websocket was complete')
ob.complete();
}
})
diff --git a/src/assets/images/page-loading.gif b/src/assets/images/page-loading.gif
new file mode 100644
index 0000000000000000000000000000000000000000..4e6ad967fe4f12b6a38c129063bc9e257ba41811
GIT binary patch
literal 1324443
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