angular 路由策略相关问题 (包含路由跳转以后原页面没有进destory方法的原因和处理)

发布时间:2024-04-25 16:01

angular中,不同路由不同页面之间跳转的时候在不做任何处理的时候是会直接销毁原页面,如果页面没有销毁,那就一定是采用了路由复用。

如下图,在没有采用路由复用的策略的时候,可以看到在页面切换的时候是会直接销毁原页面的。
\"angular

而采用了路由复用策略以后,可以看到跳转以后,原页面并没有销毁。
\"angular

要怎么做其实很简单,angular 原生提供了路由相关的接口,首先新建一个ts文件
\"angular

然后继承angular提供的路由策略接口
\"angular

对接口进行修改,代码如下

import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from \"@angular/router\";

interface RouterStroageObject {
    snapshot: ActivatedRouteSnapshot;
    handle: DetachedRouteHandle;
}

export class RouterStrategy implements RouteReuseStrategy {

    storedRoutes: { [key: string]: RouterStroageObject } = {};
    storedData: { [key: string]: any } = {};


    /**
     * 
     * 路由离开时是否需要保存页面,这是实现自定义路由复用策略最重要的一个方法。
其中:

返回值为true时,路由离开时保存页面信息,当路由再次激活时,会直接显示保存的页面。

返回值为false时,路由离开时直接销毁组件,当路由再次激活时,直接初始化为新页面。
     */
    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        // console.log(\'shouldDetach的事件中的route\', route)
        if (route.data.noReuse) {
            return false
        }
        return true
    }

    /**
如果shouldDetach方法返回true,会调用这个方法来保存页面。
     */
    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        // console.log(\'store的事件\', \'route\', route, \'handle\', handle);
        const storedRoute: RouterStroageObject = {
            snapshot: route,
            handle: handle
        }
        this.storedRoutes[this.getRouteUrl(route)] = storedRoute;
        // console.log(\'this.storedRoutes\', this.storedRoutes)
    }

    /**
     * 
路由进入页面时是否有页面可以重用。 true: 重用页面,false:生成新的页面
     */
    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        return !!route.routeConfig && !!this.storedRoutes[this.getRouteUrl(route)];
    }

    /**
     * 
路由激活时获取保存的页面,如果返回null,则生成新页面
     */
    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
        if (!route.routeConfig || route.routeConfig.loadChildren || !this.storedRoutes[this.getRouteUrl(route)]) {
            return null
        }
        return this.storedRoutes[this.getRouteUrl(route)].handle
    }

    /**
     * 
     决定跳转后是否可以使用跳转前的路由页面,即跳转前后跳转后使用相同的页面
     */
    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return future.routeConfig === curr.routeConfig && JSON.stringify(future.params) === JSON.stringify(curr.params);
    }

    private getRouteUrl(route: ActivatedRouteSnapshot) {
        //@ts-ignore
        const url = route[\'_routerState\'].url;
        const path = url.replace(/\\//g, \'_\') + \'_\' + (route.routeConfig?.loadChildren || route.routeConfig?.component?.toString().split(\'(\')[0].split(\' \')[1]);
        return path
    }

}

保存以后,在要使用的路由文件中引入

import { NgModule } from \'@angular/core\';
import { RouteReuseStrategy, RouterModule, Routes } from \'@angular/router\';
import { RouterStrategy } from \'./routerStrategy\';
import { Test1ComponentComponent } from \'./test1-component/test1-component.component\';
import { Test2ComponentComponent } from \'./test2-component/test2-component.component\';

const routes: Routes = [
  { path:\'\',pathMatch:\'full\',redirectTo:\'/test1\' },
  { path:\'test1\',component:Test1ComponentComponent,data:{noReuse:false} },
  { path:\'test2\',component:Test2ComponentComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers:[
    {provide:RouteReuseStrategy,useClass:RouterStrategy}
  ]
})
export class AppRoutingModule { }

如果我把noReuse的值改为true那么Test1页面跳转以后就会被销毁,如果设为false或者不设,跳转以后就不会被销毁
\"angular

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号