我有一个 Angular 2 模块,我在其中实现了路由,并希望在导航时存储状态。
用户应该能够:
- 使用“搜索公式”搜索文档
- 导航到其中一个结果
- 导航回“searchresult”——不与服务器通信
这可能包括 RouteReuseStrategy
。
问题是:
如何实现不应存储文档?
所以应该存储路由路径“documents”的状态,而不应该存储路由路径“documents/:id”的状态?
原文由 Anders Gram Mygind 发布,翻译遵循 CC BY-SA 4.0 许可协议
嘿安德斯,好问题!
我和你有几乎相同的用例,并且想做同样的事情!用户搜索 > 获取结果 > 用户导航到结果 > 用户导航返回 > BOOM _快速返回结果_,但您不想存储用户导航到的特定结果。
tl;博士
您需要有一个实现
RouteReuseStrategy
的类,并在ngModule
中提供您的策略。如果要在存储路由时修改,修改shouldDetach
函数。当它返回true
时,Angular 存储路由。如果想在附加路由时修改,修改shouldAttach
函数。当shouldAttach
返回 true 时,Angular 将使用存储的路由代替请求的路由。这是一个 Plunker 供您使用。关于 RouteReuseStrategy
通过问这个问题,您已经了解 RouteReuseStrategy 允许您告诉 Angular 不要 销毁组件,但实际上是保存它以备日后重新渲染。这很酷,因为它允许:
最后一个很重要,如果你想暂时离开一个页面,即使用户已经在其中输入了 很多 文本。企业应用程序会喜欢这个功能,因为表单数量 _过多_!
这就是我想出的办法来解决这个问题。正如您所说,您需要使用
RouteReuseStrategy
由 @angular/router 在 3.4.1 及更高版本中提供。去做
首先 确保你的项目有@angular/router 3.4.1 或更高版本。
接下来,创建一个文件,该文件将包含实现
RouteReuseStrategy
的类。我调用了我的reuse-strategy.ts
并将其放在/app
文件夹中以便妥善保管。现在,这个类应该是这样的:(不用担心您的 TypeScript 错误,我们即将解决所有问题)
通过为您的
app.module
提供课程来 完成基础 工作。请注意,您尚未编写CustomReuseStrategy
,但应该继续编写 ---import
它来自reuse-strategy.ts
都是一样的。还有import { RouteReuseStrategy } from '@angular/router';
最后一部分 是编写类,该类将控制路由是否分离、存储、检索和重新附加。在我们开始旧的 复制/粘贴 之前,我将在这里根据我的理解对机制做一个简短的解释。我所描述的方法可以参考下面的代码,当然, 代码中 有很多文档。
shouldReuseRoute
触发。这对我来说有点奇怪,但如果它返回true
,那么它实际上会重用您当前所在的路线,并且不会触发其他任何方法。如果用户离开,我只返回 false。shouldReuseRoute
返回false
,shouldDetach
触发。shouldDetach
判断是否要存储路由,返回一个boolean
表示。 这是你应该决定存储/不存储路径 的地方,我会通过检查你 想要 存储的路径数组route.routeConfig.path
,如果path
不返回 false存在于数组中。shouldDetach
返回true
,store
被解雇,这是你存储任何你想要的关于路线的信息的机会。无论你做什么,你都需要存储DetachedRouteHandle
因为 Angular 稍后会用它来识别你存储的组件。下面,我将DetachedRouteHandle
和ActivatedRouteSnapshot
存储到我班级的本地变量中。所以,我们已经看到了存储逻辑,但是如何导航 到 一个组件呢? Angular 是如何决定拦截你的导航并将存储的导航放到它的位置的?
shouldReuseRoute
返回false
之后,shouldAttach
运行,这是您确定是要重新生成内存还是使用组件内存的机会。如果您想重用存储的组件,请返回true
就可以了!retrieve
返回该组件的DetachedRouteHandle
来表明这一点。这几乎就是您需要的所有逻辑!在下面
reuse-strategy.ts
的代码中,我还为您留下了一个比较两个对象的漂亮函数。我用它来比较未来路线的route.params
和route.queryParams
与存储的路线。如果这些都匹配,我想使用存储的组件而不是生成一个新组件。但是你怎么做 取决于你!重用-strategy.ts
行为
此实现将用户在路由器上访问的每条唯一路由恰好存储一次。这将在整个用户在站点上的会话期间继续添加到存储在内存中的组件。如果您想限制存储的路由,可以使用
shouldDetach
方法。它控制您保存的路线。例子
假设您的用户从主页搜索某些内容,这会将他们导航到路径
search/:term
,它可能看起来像www.yourwebsite.com/search/thingsearchedfor
。搜索页面包含一堆搜索结果。你想存储这条路线,以防他们想回来!现在他们单击搜索结果并导航到view/:resultId
,您 不想 存储它,因为它们可能只存在一次。有了上面的实施,我会简单地改变shouldDetach
方法!它可能看起来像这样:首先 让我们创建一个我们想要存储的路径数组。
现在,在
shouldDetach
我们可以检查route.routeConfig.path
对照我们的阵列。因为 Angular _只会存储一个路由实例_,所以这种存储是轻量级的,我们只会存储位于
search/:term
的组件,而不是所有其他组件!附加链接
虽然目前还没有太多文档,但这里有几个链接指向现有的文档:
角度文档: https ://angular.io/docs/ts/latest/api/router/index/RouteReuseStrategy-class.html
介绍文章: https ://www.softwarearchitekt.at/post/2016/12/02/sticky-routes-in-angular-2-3-with-routereusestrategy.aspx
nativescript-angular 对 RouteReuseStrategy 的默认实现: https ://github.com/NativeScript/nativescript-angular/blob/cb4fd3a/nativescript-angular/router/ns-route-reuse-strategy.ts