Files
angular__angular/packages/router
Andrew Scott c5d0bd4966 fix(router): Prevent URL flicker when new navigations cancel ongoing ones (#43496)
This bit of code is problematic for several reasons:
1. AngularJS-specific handling should not exist in core router code if it can be avoided.
It's not something that should complicated the code long-term
2. It causes URL flickering (the `replace: /` really does happen and can be observed)
3. The original intent was likely for the URL to not actually change;
since the Router only initially supported 'deferred' navigations, this would _usually_ be the case.
4. It actually causes observers of URL changes more problems in handling changes
because the router is already about to process another navigation request.
Notice that when using `'computed'` restoration logic, we do not reset the URL
because it would cause another location change event and conflict with the new navigation.
5. It only resets the browser URL but does nothing to sync the rest of the internal state of the router.
6. It makes guards which call `router.navigate()` behave _slightly_ differently
than guard which return `UrlTree`. Guards which return `UrlTree` do not reset the
URL, but instead just trigger a new navigation.
7. It resets the entire URL rather than just the portion that the
   `UrlHandlingStrategy` is configured to handle. Theoretically, the
   Router could be configured to only handle a part of the URL so failed
   navigations should not reset parts it is not configured to touch.
   Note that this is actually a problem in other places in the router as
   well where `resetState` is not called before
   `resetUrlToCurrentUrlTree`.

As a nice benefit, when `urlUpdateStrategy` is set to `'eager'`, this
makes #17004 possible.

BREAKING CHANGE:
The router will no longer replace the browser URL when a new navigation
cancels an ongoing navigation. This often causes URL flicker and was
only in place to support some AngularJS hybrid applications. Hybrid
applications which rely on the `navigationId` being present on initial
navigations that were handled by the Angular router should instead
subscribe to `NavigationCancel` events and perform the
`location.replaceState` themselves to add `navigationId` to the Router
state.
In addition, tests which assert `urlChanges` on the `SpyLocation` may
need to be adjusted to account for the `replaceState` which is no longer
triggered.

PR Close #43496
2021-09-20 20:57:57 +00:00
..
…

Angular Router

Managing state transitions is one of the hardest parts of building applications. This is especially true on the web, where you also need to ensure that the state is reflected in the URL. In addition, we often want to split applications into multiple bundles and load them on demand. Doing this transparently isn’t trivial.

The Angular router is designed to solve these problems. Using the router, you can declaratively specify application state, manage state transitions while taking care of the URL, and load components on demand.

Guide

Read the dev guide here.