Angular 的子模块的自定义 RouteReuseStrategy
Custom RouteReuseStrategy for Angular's child module
我只想对一个模块使用此自定义路由重用策略:
export class CustomRouteReuseStrategy extends RouteReuseStrategy {
public shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
public store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
public shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { return null; }
public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return true;
}
}
所以我在名为 ChildModule
:
的模块之一中传入了 @NgModule()
providers: [
{
provide: RouteReuseStrategy,
useClass: CustomRouteReuseStrategy
}
]
不幸的是,当我将它传递到那里时,它只是被忽略了。虽然添加到我的根 AppModule
时工作正常...我不确定它是否重要,但是 ChildModule
是延迟加载的。如何解决?
我终于通过将修改后的 CustomRouteStrategy
传递给 AppModule
来实现它:
export class CustomRouteReuseStrategy extends RouteReuseStrategy {
public shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
public store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
public shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { return null; }
public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return (future.routeConfig === curr.routeConfig) || future.data.reuse;
}
}
并将data: { reuse: true }
添加到延迟加载的路由ChildModule
:
{
path: 'some-path',
data: { reuse: true },
loadChildren: './child.module#ChildModule',
},
自定义路线策略
import {RouteReuseStrategy,DetachedRouteHandle,ActivatedRouteSnapshot} from '@angular/router';
export class CustomReuseStrategy implements RouteReuseStrategy {
public static handlers: { [key: string]: DetachedRouteHandle } = {}
private static delete: string
//THIS METHOD IS USED FOR DELETE ROUTE
public static deleteRouteSnapshot(name: string): void {
if (CustomReuseStrategy.handlers[name]) {
delete CustomReuseStrategy.handlers[name];
} else {
CustomReuseStrategy.delete = name;
}
}
//THIS METHOD RETURN TRUE WHEN ROUTE REUSE LATER
public shouldDetach(route: ActivatedRouteSnapshot): boolean {
return true;
}
//THIS METHOD IS USD FOR STORE ROUTE STATE
public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
if (CustomReuseStrategy.delete && CustomReuseStrategy.delete == this.getRouteUrl(route)) {
CustomReuseStrategy.delete = null
return;
}
CustomReuseStrategy.handlers[this.getRouteUrl(route)] = handle;
}
//ATTACHED ROUTE IF ALREADY NOT PRESENT
public shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!CustomReuseStrategy.handlers[this.getRouteUrl(route)];
}
//THIS METHOD IS USED FOR RETRIEVING ROUTE STATE
public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
if (!route.routeConfig) {
return null
}
return CustomReuseStrategy.handlers[this.getRouteUrl(route)];
}
//THIS METHOD RUN WHEN USER CHANGE ROUTE EVEY TIME AND CHECK CURRENT ROUTE WANT TO USED CUSTOM STRATEGY OR NOT
public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return future.routeConfig === curr.routeConfig &&
JSON.stringify(future.params) === JSON.stringify(curr.params);
}
//FIND OUT ACTUAL ROUTE NAME AND ROUTE THE URL
private getRouteUrl(route: ActivatedRouteSnapshot) {
return route['_routerState'].url.replace(/\//g, '_')
}
}
这是我的带有子项和参数的路由的工作示例:
import {ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy} from '@angular/router';
export class CustomReuseStrategy implements RouteReuseStrategy {
handlers: { [key: string]: DetachedRouteHandle } = {};
shouldDetach(route: ActivatedRouteSnapshot): boolean {
return route.data.shouldReuse || false;
}
store(route: ActivatedRouteSnapshot, handle: {}): void {
if (route.data.shouldReuse && this.getUrl(route)) {
this.handlers[this.getUrl(route)] = handle;
}
}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!this.handlers[this.getUrl(route)];
}
retrieve(route: ActivatedRouteSnapshot): any {
if (!this.getUrl(route)) {
return null;
}
return this.handlers[this.getUrl(route)];
}
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return future.routeConfig === curr.routeConfig && JSON.stringify(future.params) === JSON.stringify(curr.params);
}
getUrl(route: ActivatedRouteSnapshot) {
if (!route.parent.url.join('/') || !route.url.join('/')) {
return null;
}
let url = '';
if (route.parent.url.join('/')) {
url += route.parent.url.join('/') + '/';
}
if (route.url.join('/')) {
url += route.url.join('/');
}
return url === '' ? null : url;
}
}
以及内部路由配置:
export const myRoute: Route = {
path: 'my',
component: MyComponent,
data: {
pageTitle: 'MY'
},
children: [
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
},
{
path: 'dashboard',
component: MyDashboardComponent,
data: {
shouldReuse: true
}
},
{
path: 'orders',
component: MyOrdersComponent,
data: {
shouldReuse: true
}
},
{
path: 'event/:id',
component: MyEventComponent,
data: {
shouldReuse: true
}
}
]
};
我只想对一个模块使用此自定义路由重用策略:
export class CustomRouteReuseStrategy extends RouteReuseStrategy {
public shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
public store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
public shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { return null; }
public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return true;
}
}
所以我在名为 ChildModule
:
providers: [
{
provide: RouteReuseStrategy,
useClass: CustomRouteReuseStrategy
}
]
不幸的是,当我将它传递到那里时,它只是被忽略了。虽然添加到我的根 AppModule
时工作正常...我不确定它是否重要,但是 ChildModule
是延迟加载的。如何解决?
我终于通过将修改后的 CustomRouteStrategy
传递给 AppModule
来实现它:
export class CustomRouteReuseStrategy extends RouteReuseStrategy {
public shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
public store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
public shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { return null; }
public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return (future.routeConfig === curr.routeConfig) || future.data.reuse;
}
}
并将data: { reuse: true }
添加到延迟加载的路由ChildModule
:
{
path: 'some-path',
data: { reuse: true },
loadChildren: './child.module#ChildModule',
},
自定义路线策略
import {RouteReuseStrategy,DetachedRouteHandle,ActivatedRouteSnapshot} from '@angular/router';
export class CustomReuseStrategy implements RouteReuseStrategy {
public static handlers: { [key: string]: DetachedRouteHandle } = {}
private static delete: string
//THIS METHOD IS USED FOR DELETE ROUTE
public static deleteRouteSnapshot(name: string): void {
if (CustomReuseStrategy.handlers[name]) {
delete CustomReuseStrategy.handlers[name];
} else {
CustomReuseStrategy.delete = name;
}
}
//THIS METHOD RETURN TRUE WHEN ROUTE REUSE LATER
public shouldDetach(route: ActivatedRouteSnapshot): boolean {
return true;
}
//THIS METHOD IS USD FOR STORE ROUTE STATE
public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
if (CustomReuseStrategy.delete && CustomReuseStrategy.delete == this.getRouteUrl(route)) {
CustomReuseStrategy.delete = null
return;
}
CustomReuseStrategy.handlers[this.getRouteUrl(route)] = handle;
}
//ATTACHED ROUTE IF ALREADY NOT PRESENT
public shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!CustomReuseStrategy.handlers[this.getRouteUrl(route)];
}
//THIS METHOD IS USED FOR RETRIEVING ROUTE STATE
public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
if (!route.routeConfig) {
return null
}
return CustomReuseStrategy.handlers[this.getRouteUrl(route)];
}
//THIS METHOD RUN WHEN USER CHANGE ROUTE EVEY TIME AND CHECK CURRENT ROUTE WANT TO USED CUSTOM STRATEGY OR NOT
public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return future.routeConfig === curr.routeConfig &&
JSON.stringify(future.params) === JSON.stringify(curr.params);
}
//FIND OUT ACTUAL ROUTE NAME AND ROUTE THE URL
private getRouteUrl(route: ActivatedRouteSnapshot) {
return route['_routerState'].url.replace(/\//g, '_')
}
}
这是我的带有子项和参数的路由的工作示例:
import {ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy} from '@angular/router';
export class CustomReuseStrategy implements RouteReuseStrategy {
handlers: { [key: string]: DetachedRouteHandle } = {};
shouldDetach(route: ActivatedRouteSnapshot): boolean {
return route.data.shouldReuse || false;
}
store(route: ActivatedRouteSnapshot, handle: {}): void {
if (route.data.shouldReuse && this.getUrl(route)) {
this.handlers[this.getUrl(route)] = handle;
}
}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!this.handlers[this.getUrl(route)];
}
retrieve(route: ActivatedRouteSnapshot): any {
if (!this.getUrl(route)) {
return null;
}
return this.handlers[this.getUrl(route)];
}
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return future.routeConfig === curr.routeConfig && JSON.stringify(future.params) === JSON.stringify(curr.params);
}
getUrl(route: ActivatedRouteSnapshot) {
if (!route.parent.url.join('/') || !route.url.join('/')) {
return null;
}
let url = '';
if (route.parent.url.join('/')) {
url += route.parent.url.join('/') + '/';
}
if (route.url.join('/')) {
url += route.url.join('/');
}
return url === '' ? null : url;
}
}
以及内部路由配置:
export const myRoute: Route = {
path: 'my',
component: MyComponent,
data: {
pageTitle: 'MY'
},
children: [
{
path: '',
redirectTo: 'dashboard',
pathMatch: 'full'
},
{
path: 'dashboard',
component: MyDashboardComponent,
data: {
shouldReuse: true
}
},
{
path: 'orders',
component: MyOrdersComponent,
data: {
shouldReuse: true
}
},
{
path: 'event/:id',
component: MyEventComponent,
data: {
shouldReuse: true
}
}
]
};