-
Notifications
You must be signed in to change notification settings - Fork 10k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow cancellation of navigation events in Blazor #42638
Conversation
Added a safeguard to ensure overlapping navigations are correctly canceled during high network latency scenarios.
public CancellationToken CancellationToken { get; }
public bool IsCanceled { get; }
public void Cancel(); This triplet could be confusing, because we're using the word "cancel" to mean two different things (if I'm following correctly). The I'd suggest we disambiguate by not using the phrase "cancel" about the navigation itself, and saying something like "PreventNavigation" instead, e.g.: public CancellationToken CancellationToken { get; }
public void PreventNavigation();
public bool IsNavigationPrevented { get; } |
Also to be honest, I'm not sure what is the use case for What if instead, there was just I'm not 100% sure how usable this would end up being (whether there are any cases where people would have to suppress a TaskCancelledException) but on the surface it seems like it might be a valid and simple pattern. |
More API thoughts:
I'm guessing this is the destination location, not the current location, but just to be clear maybe rename to UPDATE I now realise that
Do we need this info? If it's a client-originated navigation ( |
src/Components/Components/src/Routing/InternalNavigationLock.cs
Outdated
Show resolved
Hide resolved
@javiercn I've addressed some of your feedback around cancellation and added some unit tests (with a few more still remaining). /cc @SteveSandersonMS in case you have any thoughts about the recent modifications. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look great, I have a couple of open questions/suggestions left, but this will be ready to go after resolving those.
I think I get what you are saying and that's a valid reason to keep the cancellation token in the same place. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great!
Thanks @MackinnonBuck for persevering through all the nuances on the implementation details.
We still need to solve the problem we are discussing offline, but I am signing off already as I think we will be good to go after that.
It looks great to me. Reading through the comments, it seems like this has been worked out in great detail now. Thanks also to @javiercn for the quality feedback. |
I'm going to merge this now - I will address any further feedback in a follow-up PR along with the API review feedback. Thank you @SteveSandersonMS and @javiercn for your detailed feedback and collaboration on this! |
Allow cancellation of navigation events in Blazor
Introduces new APIs that enable the cancellation of internal and external navigation events.
API Overview
New
NavigationManager
APIs can be used to add and remove handlers that may asynchronously cancel internal navigations:The
<NavigationLock />
component wraps these APIs so this functionality can easily be added to a Blazor component:When
ConfirmExternalNavigation
istrue
, the browser's built-in confirmation dialog prompts the user if they would like to continue before performing an external navigation.Important behavioral considerations
Since internal navigations can be canceled asynchronously, it's possible that multiple overlapping navigations may occur. These might include cases where the user is rapidly clicking the back button on a page or clicking multiple links before a decision about whether to permit the navigation is made. Following is a summary of how this asynchrony is handled:
It's also important to note that the
<NavigationLock />
component only takes effect after being rendered (just like any other Blazor component). Practically, this means it's possible that the user may quickly navigate past a page that was supposed to intercept the navigation, but it didn't because the user navigated away before the component had a chance to render.Some other details to be aware of:
NavigationManager.NavigateTo()
) will also invoke the "location changing" handlers.Fixes #14962