栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何为Angular 2中的特定路线实施RouteReuseStrategy应该发布

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何为Angular 2中的特定路线实施RouteReuseStrategy应该发布

嗨,安德斯,很好的问题!

我有几乎与您相同的用例,并且想做同样的事情!用户搜索>获取结果>用户导航到结果>用户导航> BOOM 迅速恢复结果
,但是您不希望存储用户导航到的特定结果。

tl; dr

您需要具有一个类,该类在中实现

RouteReuseStrategy
并提供您的策略
ngModule
。如果要在存储路径时进行修改,请修改
shouldDetach
功能。返回时
true
,Angular将存储路线。如果要在连接路由时进行修改,请修改
shouldAttach
功能。当
shouldAttach
返回true时,Angular将使用存储的路线代替请求的路线。这是一个Plunker供您玩耍。

关于RouteReuseStrategy

通过询问这个问题,您已经了解到RouteReuseStrategy允许您告诉Angular 不要
破坏组件,而实际上是保存它以便以后重新渲染。这很酷,因为它允许:

  • __服务器调用 减少
  • 提高 速度
  • 并且 ,默认情况下,组件以与原始状态相同的状态进行渲染

如果您想暂时离开某个页面,即使用户在其中输入了 很多 文本,那么最后一个页面也很重要。企业应用程序会喜欢这种功能,因为表单数量 过多

这就是我想出的解决问题的方法。如您所说,您需要利用

RouteReuseStrategy
3.4.1及更高版本中@ angular /
router提供的功能。

去做

首先, 请确保您的项目具有@ angular / router 3.4.1或更高版本。

接下来 ,创建一个文件来存放要实现的类

RouteReuseStrategy
。我打电话给我
reuse-strategy.ts
,并将其放在
/app
文件夹中以进行保管。现在,此类应如下所示:

import { RouteReuseStrategy } from '@angular/router';export class CustomReuseStrategy implements RouteReuseStrategy {}

(不必担心您的Typescript错误,我们将解决所有问题)

通过为您的课程提供 基础知识
完成基础工作

app.module
。请注意,您尚未编写
CustomReuseStrategy
,但是应该
import
从头开始
reuse-strategy.ts
。也
import { RouteReuseStrategy } from '@angular/router';

@NgModule({    [...],    providers: [        {provide: RouteReuseStrategy, useClass: CustomReuseStrategy}    ])}export class AppModule {}

最后一部分 是编写类,该类将控制是否分离,存储,检索和重新连接路由。在我理解旧的 复制/粘贴之前
,我将在这里对机制进行简短的解释。请参考以下代码,了解我正在描述的方法,当然, 代码中 有大量文档。

  1. 导航时
    shouldReuseRoute
    会触发。这对我来说有点奇怪,但是如果返回
    true
    ,那么它实际上会重用您当前使用的路由,并且不会触发其他任何方法。如果用户正在导航,我只会返回false。
  2. 如果
    shouldReuseRoute
    返回
    false
    ,则
    shouldDetach
    触发。
    shouldDetach
    确定您是否要存储路线,并返回一个
    boolean
    指示。 这是您应该决定存储/不存储路径的地方 ,我可以通过检查 存储的路径数组来完成
    route.routeConfig.path
    ,如果
    path
    数组中不存在false,则返回false 。
  3. 如果
    shouldDetach
    return
    true
    ,将
    store
    被触发,这是您存储有关路线的任何信息的机会。无论您做什么,都需要存储,
    DetachedRouteHandle
    因为Angular稍后会使用它来标识已存储的组件。在下面,我将
    DetachedRouteHandle
    和都存储
    ActivatedRouteSnapshot
    到类的局部变量中。

因此,我们已经了解了存储的逻辑,但是导航 组件又如何呢?Angular如何决定拦截您的导航并将已存储的导航放置在原处?

  1. 同样,
    shouldReuseRoute
    返回后
    false
    shouldAttach
    运行,这是您确定是要重新生成还是使用内存中组件的机会。如果您想重用存储的组件,请返回
    true
    ,一切顺利!
  2. 现在,Angular会问您“您要我们使用哪个组件?”,您将通过
    DetachedRouteHandle
    从返回该组件来进行指示
    retrieve

这几乎就是您需要的所有逻辑!在

reuse-strategy.ts
下面的代码中,我还为您提供了一个比较两个对象的漂亮函数。我用它来比较将来的路线
route.params
route.queryParams
已存储的路线。如果所有这些都匹配,我想使用存储的组件,而不是生成一个新组件。但是,如何操作
取决于您!

重用策略

import { ActivatedRouteSnapshot, RouteReuseStrategy, DetachedRouteHandle } from '@angular/router';interface RouteStorageObject {    snapshot: ActivatedRouteSnapshot;    handle: DetachedRouteHandle;}export class CustomReuseStrategy implements RouteReuseStrategy {        storedRoutes: { [key: string]: RouteStorageObject } = {};        shouldDetach(route: ActivatedRouteSnapshot): boolean {        let detach: boolean = true;        console.log("detaching", route, "return: ", detach);        return detach;    }        store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {        let storedRoute: RouteStorageObject = { snapshot: route, handle: handle        };        console.log( "store:", storedRoute, "into: ", this.storedRoutes );        // routes are stored by path - the key is the path name, and the handle is stored under it so that you can only ever have one object stored for a single path        this.storedRoutes[route.routeConfig.path] = storedRoute;    }        shouldAttach(route: ActivatedRouteSnapshot): boolean {        // this will be true if the route has been stored before        let canAttach: boolean = !!route.routeConfig && !!this.storedRoutes[route.routeConfig.path];        // this decides whether the route already stored should be rendered in place of the requested route, and is the return value        // at this point we already know that the paths match because the storedResults key is the route.routeConfig.path        // so, if the route.params and route.queryParams also match, then we should reuse the component        if (canAttach) { let willAttach: boolean = true; console.log("param comparison:"); console.log(this.compareObjects(route.params, this.storedRoutes[route.routeConfig.path].snapshot.params)); console.log("query param comparison"); console.log(this.compareObjects(route.queryParams, this.storedRoutes[route.routeConfig.path].snapshot.queryParams)); let paramsMatch: boolean = this.compareObjects(route.params, this.storedRoutes[route.routeConfig.path].snapshot.params); let queryParamsMatch: boolean = this.compareObjects(route.queryParams, this.storedRoutes[route.routeConfig.path].snapshot.queryParams); console.log("deciding to attach...", route, "does it match?", this.storedRoutes[route.routeConfig.path].snapshot, "return: ", paramsMatch && queryParamsMatch); return paramsMatch && queryParamsMatch;        } else { return false;        }    }        retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {        // return null if the path does not have a routerConfig OR if there is no stored route for that routerConfig        if (!route.routeConfig || !this.storedRoutes[route.routeConfig.path]) return null;        console.log("retrieving", "return: ", this.storedRoutes[route.routeConfig.path]);                return this.storedRoutes[route.routeConfig.path].handle;    }        shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {        console.log("deciding to reuse", "future", future.routeConfig, "current", curr.routeConfig, "return: ", future.routeConfig === curr.routeConfig);        return future.routeConfig === curr.routeConfig;    }        private compareObjects(base: any, compare: any): boolean {        // loop through all properties in base object        for (let baseProperty in base) { // determine if comparrison object has that property, if not: return false if (compare.hasOwnProperty(baseProperty)) {     switch(typeof base[baseProperty]) {         // if one is object and other is not: return false         // if they are both objects, recursively call this comparison function         case 'object':  if ( typeof compare[baseProperty] !== 'object' || !this.compareObjects(base[baseProperty], compare[baseProperty]) ) { return false; } break;         // if one is function and other is not: return false         // if both are functions, compare function.toString() results         case 'function':  if ( typeof compare[baseProperty] !== 'function' || base[baseProperty].toString() !== compare[baseProperty].toString() ) { return false; } break;         // otherwise, see if they are equal using coercive comparison         default:  if ( base[baseProperty] != compare[baseProperty] ) { return false; }     } } else {     return false; }        }        // returns true only after false HAS NOT BEEN returned through all loops        return true;    }}

行为

此实现将用户访问的每个唯一路由准确地存储在路由器上一次。这将继续添加到站点上整个用户会话中存储在内存中的组件。如果您想限制您存储的路线,则可以使用该

shouldDetach
方法。它控制着您保存的路由。

假设您的用户从首页中搜索了一些内容,然后将其导航到该路径

search/:term
,该路径可能显示为
www.yourwebsite.com/search/thingsearchedfor
。搜索页面包含一堆搜索结果。您想存储这条路线,以防他们想回来!现在,他们点击一个搜索结果,并获得导航到
view/:resultId
,你
希望店,看到他们很可能会出现一次。完成上述实现后,我只需更改
shouldDetach
方法即可!可能是这样的:

首先, 让我们创建一个要存储的路径数组。

private acceptedRoutes: string[] = ["search/:term"];

现在,

shouldDetach
我们可以
route.routeConfig.path
对照数组检查。

shouldDetach(route: ActivatedRouteSnapshot): boolean {    // check to see if the route's path is in our acceptedRoutes array    if (this.acceptedRoutes.indexOf(route.routeConfig.path) > -1) {        console.log("detaching", route);        return true;    } else {        return false; // will be "view/:resultId" when user navigates to result    }}

由于Angular将仅存储路线的一个实例,因此该存储将是轻量级的,我们将仅存储位于

search/:term
而不是所有其他组件的组件!



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/405037.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号