Angular4中 ActivatedRoute 和 ActivatedRouteSnapshot 的区别是什么

角度4的 ActivatedRouteSnapshotActivatedRoute的区别是什么?我的理解是 ActivatedRouteSnapshotActivatedRoute的子代,也就是说 ActivatedRoute包含 ActivatedRouteSnapshot

顺便说一句,我试着在谷歌上搜索这个问题的答案,但是我没有发现任何一个搜索结果是可以理解的。

谢谢!

76235 次浏览

Since ActivatedRoute can be reused, ActivatedRouteSnapshot is an immutable object representing a particular version of ActivatedRoute. It exposes all the same properties as ActivatedRoute as plain values, while ActivatedRoute exposes them as observables.

Here is the comment in the implementation:

export class ActivatedRoute {
/** The current snapshot of this route */
snapshot: ActivatedRouteSnapshot;

If a router reuses a component and doesn't create a new activated route, you will have two versions of ActivatedRouteSnapshot for the same ActivatedRoute. Suppose you have the following routing configuration:

path: /segment1/:id,
component: AComponent

Now you navigate to:

/segment1/1

You will have the param in the activatedRoute.snapshot.params.id as 1.

Now you navigate to:

/segment1/2

You will have the param in the activatedRoute.snapshot.params.id as 2.

You can see it by implementing the following:

export class AComponent {
constructor(r: ActivatedRoute) {
r.url.subscribe((u) => {
console.log(r.snapshot.params.id);
});

There are 2 ways to get the parameter from the route.

1. Snapshot (route.snapshot.paramMap.get). Read it during init.

Use the Snapshot if you only need the initial value of the parameter once during the component's initialization, and don't expect the URL to change while the user is still on that same component.

  • I.e. if on a product/2 route, and the only way they'd get to product/3 is by going back to the product search screen and then clicking a product detail (leaving the detail component, then re-opening it with a new route param)

2. Observable (route.paramMap.subscribe). Subscribe to it during init.

Use the Observable if it's possible for the route to change while the user is still on the same component, and hence the Component's initialization would not be called again, but the observable would call your subscribed logic when the URL changed.

  • I.e. if on a product/2 route, and you have a "next" button to go to the next id record product/3, hence the user did not leave/re-open the component but the URL did receive a new param.

Generally speaking, subscribing is the safest route if you're unsure.

One of the key differences not highlighted by the other answers here is the fact that ActivatedRoute can be injected into a component, while ActivatedRouteSnapshot cannot.

As mentioned in this answer, you access ActivatedRouteSnapshot in a component by injecting ActivatedRoute, and then accessing its snapshot property, like so:

constructor(route: ActivatedRoute) {
let activatedRouteSnapshot = route.snapshot;
}

On the other hand, trying to inject ActivatedRouteSnapshot directly into the component will result in an error like this:

ERROR Error: Uncaught (in promise): Error: StaticInjectorError(AppModule)[YourComponent -> ActivatedRouteSnapshot]: StaticInjectorError(Platform: core)[YourComponent -> ActivatedRouteSnapshot]: NullInjectorError: No provider for ActivatedRouteSnapshot!

See also the documentation for ActivatedRoute and ActivatedRouteSnapshot