在 Angular 中获取查询字符串的不同方法

Different approaches to getting the query string in Angular

我想获取查询字符串参数。我可以在组件的 constructor()ngOnInit() 中完成。此外,有两种方法可以做到这一点:

// option (1)
const foo = this.activatedRoute.snapshot.queryParamMap.get("foo");
//use foo...

// option (2)
const subscription = this.activatedRoute.queryParamMap.subscribe(params => {
  const foo = params["foo"];
  //use foo...
});
// ...and remember to unsubscribe in `ngOnDestroy()`

有很多人在获取查询字符串时遇到问题,答案总是使用选项 (1) 或 (2),但从来没有解释为什么.两种方法我都用过,到目前为止我从来没有遇到过问题。

所以:

Option(1) - 这个选项很好,它很简单,如果你不希望 queryString 会改变,那么我会坚持这个。

Option(2) - 这个选项仍然可以,但更复杂,因为你需要订阅它。但是,此选项有优势 - 您可以对 URL 更改做出反应。因此,如果您预计这个 URL 会在组件运行时发生变化,那么请随意使用此选项。

顺便说一句。您不需要取消订阅它,因为 ActivatedRoute 及其可观察对象与路由器本身隔离。路由器在不再需要时销毁路由组件,注入的 ActivatedRoute 随之消失。

当谈到你应该在哪里初始化它时,构造函数是更好的地方来做这个,更少的代码而且你的 URL 在 OnInit Hook 之前已经准备好了,所以你可以更快地使用它。我正在使用构造函数(顾名思义)来构造变量。

关于将代码放在哪里,使用 constructor() 来设置依赖注入而不是其他。 ngOnInit() 比 "start" 更好。 where/when 组件的绑定已解析。

关于一次获取值或订阅,这在一定程度上取决于您的应用程序的工作方式。如果您的应用程序将使用新参数更改 URL 而无需重新加载页面 angular 将不会重新 运行 ngOnInit 方法,因此您的组件将不会对新值做出适当的反应。这取决于您是否订阅此更改和 运行 您的逻辑。

A link by @johnrsharp above, led me to this stackblitz 这是一个绝妙的视觉解释。

另外:

  • 如果您永远不会更改组件内的路线,请使用 route.snapshot.queryParamMap。所以原始快照就足够了。
  • 当您从组件内更改路由时使用 route.queryParamMap.subscribe,因此您需要对最新值做出反应。

我在 ngOnInit() 中执行此操作,因为 UI 是在那个时候设置的,所以没有任何未定义的可能性。基本上,它避免了竞争条件。