-
Notifications
You must be signed in to change notification settings - Fork 10.2k
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
[Blazor] Add support for confirming navigations #40149
Comments
Can the use of |
@DaveNay that seems like a reasonable ask. I think we should be able to support a callback for anchor tags / if the navigation is handled by Blazor's routing. |
Thanks for contacting us. We're moving this issue to the |
not already supporting onlocationchanging and cancel of navigation is just crazy! also LocationChanged doesn't work when loading a page outside the current blazor app and Dispose() methods on the razor components are not even called when exiting the app.. hahaha I'm sure you will add this to .Net 10 planning haha |
I guess for me, I just never really understood why it was such a performance issue. If you can plug into the browser navigation system enough to cancel a navigation, then why wouldn't you:
What about that is a performance problem? |
I can't say that I'm happy with this. There's no control for the programmer, just another popup box that we have little control over. I want to stop Navigation in a dirty form, and potentially show an in-form alert or toast. A simple bool If the changed proposed above was implemented, I don't think I would use it in the majority of circumstances, just as I don't use the Can we not do something with the Server JS interop call so we can plug in another Navigation Manager, as we can do with WASM? I'm guessing it wasn't designed that way, but... I'll have a think about that. |
100% agree with this. We implemented Baking in a If I can build a router using crossroads + history in javascript to handle this (which was based off the ASP.NET Core Knockout SPA template, BTW) then this problem can be solved in Blazor too. |
Like other commenters here I would advise against using I would also caution to use the beforeunload event in conjunction with
(This was also the reason this event wasn't used in the above-mentioned PR, as its implementation and usefulness varied amongst browsers) Although this proposal initially seems simpler than #24417 I would argue the complexity will approach that of the PR, as you still want to be able to cancel navigation in all the below cases:
And without using This proposal would also get rid of the additional Browser -> Server interaction (only when using Blazor Server, and which in the original PR would only be incurred when the developer had actually implemented an EventHandler) but at a high cost of losing all the flexibility and customizability that having a LocationChanging event in C# would bring. And personally, the performance impact of that additional Browser -> Server interaction in that PR is negligible, as it will
As the original author of #24417 I admit I might be biased towards a similar solution, And although @pranavkm explicitly stated that this was out-of-scope, maybe we could build upon it while addressing some of the criticism. I would love to take another crack at this problem. |
Thanks for contacting us. We're moving this issue to the |
As others have said, a limited solution will not suffice. We do not want to be boxed into using the EditForm or the built-in browser dialog. LocationChanging event with a cancellable event arg is the obvious and natural way to solve this. I do not understand the technical arguments for why it is not feasible. Is the issue related to providing a solution that works on Blazor Server and WASM? All SPA frameworks that I have used provide a simple way to prevent a route change. And the wait for this feature is beyond frustrating. We have a very large medical app that we are porting to Blazor and in nearly every product demo I get asked about this feature. At this point, I would switch to a 3rd party router if I found a reliable one. |
I think a simple cancellable event on the router would be good enough. We can live with the limitation of only being able to prevent navigations initiated from within blazor. Navigations initiated outside of blazor should be left to the developer to solve (which is an issue with any web based development). |
I have updated my implementation which is here - https://github.com/ShaunCurtis/Blazr.Demo.Routing. The basics are a lightly modified You can write your own I've included two
The library also includes a component for JS interaction with This is what I intend to use in the future. |
Has some plan of action been decided on this? This is an essential feature that is sorely lacking. |
IMHO, something is better than nothing. This is a big miss and having a partial solution would be much better than waiting for a perfect solution. |
I have seen mention of - "A LocationChanging event for NavigationManager (implement logic that occurs before navigation takes place)" Awaiting details. |
I've just made my own version of a library that blocks navigation on demand. It was inspired by the method used by Shaun's library (I was initially hoping to use a different method, but the DI was uncooperative) but isn't descended from it and isn't directly swappable (and has one component with the same name but a different function, just to be extra confusing). I basically started with a clean copy of the latest .NET 6 router code (it would be really nice if a lot less things were internal and didn't have to be duplicated!) and hooked in an alternative I've only tested it in WebAssembly, although I don't think there's any inherent reason why it couldn't work on Server too. (And yes, a |
I don't understand the performance concerns. Blazor already handles the navigation. I'm sure there are plenty of other ways this could be done without an issue. Was surprised to find this didn't already exist. I agree with the users above in terms of using custom prompts as apposed to the ones provided by the default browser. Think of something like Discord. When you don't save and try to navigate the page shakes and warns you. I am not a UI designer but even I know if you replaced that with an browser alert it would kill the overall feel of the app. |
I've been using this approach in Blazor Server for some time and I have noticed, that using javascript |
Also waiting for this feature. Even the browser-window is better than nothing. |
Closing, since this was handled in #42877 |
Summary
Support for Location change event is a very popular ask from our users. Unfortunately, given the nature of the event adding support for it that uses browser intrinsic is going to be difficult / impossible. #24417 attempted to solve this by hijacking browser navigation and managing it via Blazor. This is a fairly involved solution, with possible significant perf overhead, and we'd like to determine if using a narrower solution would suffice here.
A popular theme in the issue focused on preventing navigation to avoid losing unsaved changes in a component. A well-upvoted comment provides a sample for just this - https://github.com/ShaunCurtis/Blazr.Demo.EditForm/tree/master/Blazr.NavigationLocker. This spec is a way to determine if this is something we could get away with.
Motivation and goals
In-scope
Out-of-scope
Proposed solution
We introduce an API on
NavigationManager
that allows users to confirm when a navigation is to occur.AddNavigationConfirmationAsync
returns anIAsyncDisposable
which prompts for a confirmation until the returned value is disposed.public class NavigationManager { + public ValueTask<IAsyncDisposable> AddNavigationConfirmationAsync(string message, CancellationToken cancellationToken); }
Here's an example of it in use:
The implementation relies on window.confirm for a navigation that is handled via Blazor's routing and beforeunload event for all other navigation. The
message
parameter is used as part of theconfirm
dialog, but is likely to be ignored by the unload event since browsers do not consistently support specifying it.In addition to this, we introduce a
LockNavigationWhenDirty
component that usesEditContext
's dirty state (IsModified() /
MarkAsUnmodified()`) to add / remove navigation confirmations. Here is what this component looks like:Usage:
The text was updated successfully, but these errors were encountered: