Skip to content
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

Expose location changing event for NavigationManger #14962

Closed
Postlagerkarte opened this issue Oct 13, 2019 · 54 comments · Fixed by #42638
Closed

Expose location changing event for NavigationManger #14962

Postlagerkarte opened this issue Oct 13, 2019 · 54 comments · Fixed by #42638
Assignees
Labels
affected-medium This issue impacts approximately half of our customers area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-blazor-builtin-components Features related to the built in components we ship or could ship in the future Needs: Design This issue requires design work before implementating. Priority:1 Work that is critical for the release, but we could probably ship without severity-major This label is used by an internal tool User Story A single user-facing feature. Can be grouped under an epic.
Milestone

Comments

@Postlagerkarte
Copy link

The NavigationManager exposes

LocationChanged | An event that fires when the navigation location has changed.

but it does not expose a LocationChanging event.

Such an event that occurs before navigation takes place is very useful because it allows the previous view to prepare for its deactivation, for example, to display a warning, cancel navigation or silently save changes.

Can you provide such a feature or is there already another way to achieve the above?

@javiercn javiercn added the area-blazor Includes: Blazor, Razor Components label Oct 14, 2019
@javiercn
Copy link
Member

Thank you for your feature request @Postlagerkarte.

We'll consider this feature during the next release planning period and update the status of this issue accordingly.

@mkArtakMSFT mkArtakMSFT added this to the Backlog milestone Oct 14, 2019
@mkArtakMSFT mkArtakMSFT added the enhancement This issue represents an ask for new feature or an enhancement to an existing one label Oct 14, 2019
@Tiberriver256
Copy link

Not sure if this is what the OP was after with LocationChanging but it would be nice to have LocationChangeStart and LocationChangeEnd events. The use case for me would be to display a little progress bar to the user while navigation is happening.

@DanielHWe
Copy link

It would be nice to cancel the navigation to. Use Case is that the user has unsaved changes and show an error to him so he is not leaving without save.

@Postlagerkarte
Copy link
Author

Postlagerkarte commented Jan 3, 2020

I hope that the team decides to give us a full set of methods, properties, and events to support navigation including easy access to the navigation history.

Such an improved version of the NavigationManager would certainly allow tracking the lifetime of a navigation via events like:

Navigating
Navigated
NavigationProgress
NavigationFailed
NavigationStopped

Basically, hoping for an improved/adjusted version of the NavigationService 😃

@ShaunCurtis
Copy link

ShaunCurtis commented Mar 16, 2020

Yes, it's great being able to develop an SPA application, but when the user can navigate away with changes unsaved, and no way to warn them, that's a serious flaw. You can use the javascript window.history.forward() trick in the _Hosts.html file to force the user back, but that refreshes the page losing all unsaved changes. For critical editing, I'm starting to use a state service to preserve changes, but it's a bit of a cludge to get round the problem.

@aaronhudon
Copy link

If anyone can post suggestions on how best to implement this in SSB without waiting for Microsoft, please do so here.

@lucianotres
Copy link

And would be nice to have a way to handle history stack or just a simple "location.replace(url);"
Only way I found to do this currently, was with JS interop.
js like this:

window.controles_interop = {
    ...
    location_replace: function (url) {
        window.location.replace(url);
    }
};

then call:
await JSRuntime.InvokeVoidAsync("controles_interop.location_replace", $"/protocolo/{_id.Value}");

I mean something like this, so more practical:
_nav.NavigateTo($"/protocolo/{_id.Value}", replace: true);

@javiercn
Copy link
Member

@lucianotres We are adding that in a future update I think, but you don't need anything special to do that today, you can simply call JSRuntime.InvokeAsync("location.replace", url) and that will work

@OlegQu
Copy link

OlegQu commented May 18, 2020

Are there any news about this issue's status?
May be there are some possibilities to override or extend functions from EventDelegator.ts or NavigationManager.ts or use own NavigationManager.cs realization with scripts duplicating above default? Sorry, if this question sounds kind of... elementary - i'm still novice at coding.

@ShaunCurtis
Copy link

Hi,
I've been flat out on a project where I've resolved most of the issues I had. I'm just finishing testing and hoping to publish something covering the subject later this week/next week. My basic approach has been:

  1. Use the window.onbeforeunload event to warn the user that they are leaving the "application". You don't much control over this, but it works and users I have tested it on got the message.
    Place it in the _Host.cshtml.
  2. Use a scoped data service class to track the condition (dirty/clean) of the edited record.
  3. Use a scoped user session service class to temporarily hold page routing data while transitioning between routes. This also helps on the transition from New to Edit when first saving a record.
  4. Customize the standard router to check the save state of the record and either navigate or instruct the current page that the user is trying to leave and an "Are You Sure/Unsaved Data" action is required. Note that the NavigationManager only catches navigation changes and raises the LocationChanged event, the router registers with this event and does the actual work.

The key here is to get your head around what's actually going on, and what the various classes/objects are up to.

With this approach I no longer need to tamper with the back/forward history - the router handles "In Application" page changes and onbeforeunload warns the user if they are trying to navigate away.

Note that creating a customized version of the router isn't trivial. You will need to make copies of various other classes that are namespace restricted.

I'll put a post here when I have something polished enough to publish.

@OlegQu
Copy link

OlegQu commented May 18, 2020

@ShaunCurtis thanks for reply!
I already implemented steps 1 and 2. Should be enough to override OnLocationChanged event in Router class? And add there:
if (hasChanges) _jsRuntime.InvokeAsync("onbeforeHandler");
And then just change all classes referenced with Router. Or this is not so simple?
I have troubles with overriding Router, cause there are a lot of dependencies and idk how to register and use them after implementing. So I will look forward to see your approach (no matter how polished it is)!
Thanks for your attention!

@ArrowtheArcher
Copy link

ArrowtheArcher commented Jun 17, 2020

@ShaunCurtis struggling with step 4 cannot wrap my head around it is there any other way right now? is solution for this still in progress?

@ShaunCurtis
Copy link

I'm currently working on putting a working example together - literally as I write this. Hopefully I'll have something in the next day or two. This will include the "unwrapped" router code.

@ShaunCurtis
Copy link

I've now published the routing on GitHub with a working example project. You can install the DLL via a Nuget Package (I hope!). The source code is all there in the GitHub repository.

https://github.com/ShaunCurtis/CEC.Routing

@ShaunCurtis
Copy link

I've added a further project - CEC.FormControls - that uses the router with a more polished editor component similar to what I've been using in my projects. It uses enhanced Blazor InputBase Controls and the EditContext to manage editor control and routing. The Github repository is here:

https://github.com/ShaunCurtis/CEC.FormControls

@dfkeenan
Copy link

I just put CEC.Routing in my project. Works quite nicely. Thanks @ShaunCurtis .

@nemtajo
Copy link

nemtajo commented Aug 2, 2020

Hi @ShaunCurtis. Thanks! Will this library work for web assembly project as well? I need to rewrite URL to redirect URL to always remove or always add a port. For example: localhost:5001/authorize to localhost/authorize. Is this possible with your library?

@ShaunCurtis
Copy link

Hi Nemtajo,
While the functionality isn't built in, you can download the code from the repository and add it. In your case you will need to update the _locationabsolute private property in either the OnLocationChanged or Refresh Methods in the RecordRouter class. However, if you are changing the URL then you aren't routing but doing normal navigation???

@nemtajo
Copy link

nemtajo commented Aug 5, 2020

I found a much simpler method, In Startup.cs of the server project I added:


            app.UseStaticFiles(new StaticFileOptions()
            {
                OnPrepareResponse = (context) =>
                {
                    var request = context.Context.Request;
                    var response = context.Context.Response;
                    UrlRewriteUtils.AddPortIfLocalHost(request, response);
                }
            });


    public class UrlRewriteUtils
    {
        public static void AddPortIfLocalHost(HttpRequest request, HttpResponse response)
       {
           string url = request.GetDisplayUrl();
            if (url.Contains("localhost/authorize"))
            {
                var newUrl = url.Replace("localhost/authorize", "localhost:5001/authorize");
                response.Redirect(newUrl.ToString(), true);
            }
        }
    }

I used this as a reference: //https://stackoverflow.com/questions/51105799/how-do-i-force-https-redirect-on-static-files-in-asp-net-core-2-1

@mkArtakMSFT mkArtakMSFT added affected-medium This issue impacts approximately half of our customers severity-major This label is used by an internal tool labels Oct 7, 2020 — with ASP.NET Core Issue Ranking
@ghost
Copy link

ghost commented Oct 9, 2020

Thanks for contacting us.
We're moving this issue to the Next sprint planning milestone for future evaluation / consideration. We will evaluate the request when we are planning the work for the next milestone. To learn more about what to expect next and how this issue will be handled you can read more about our triage process here.

@pranavkm
Copy link
Contributor

Given there are some challenges to supporting this feature as-is across different flavors of Blazor, our team is trying trying to gauge if a more limited solution would suffice here based on this feature spec: #40149. Could you look at it and give us feedback? Thanks!

@mkArtakMSFT mkArtakMSFT modified the milestones: 7.0-preview5, .NET 7.0 May 18, 2022
@Pilchie Pilchie removed this from the .NET 7.0 milestone May 23, 2022
@mkArtakMSFT mkArtakMSFT added this to the 7.0-preview6 milestone May 25, 2022
@javiercn javiercn modified the milestones: 7.0-preview6, 7.0-preview7 Jun 15, 2022
@mkArtakMSFT mkArtakMSFT modified the milestones: 7.0-preview7, 7.0-rc1 Jul 18, 2022
@ghost ghost locked as resolved and limited conversation to collaborators Aug 21, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affected-medium This issue impacts approximately half of our customers area-blazor Includes: Blazor, Razor Components enhancement This issue represents an ask for new feature or an enhancement to an existing one feature-blazor-builtin-components Features related to the built in components we ship or could ship in the future Needs: Design This issue requires design work before implementating. Priority:1 Work that is critical for the release, but we could probably ship without severity-major This label is used by an internal tool User Story A single user-facing feature. Can be grouped under an epic.
Projects
None yet
Development

Successfully merging a pull request may close this issue.