-
Notifications
You must be signed in to change notification settings - Fork 10.3k
Navigate with "replace" param #33751
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
Conversation
/// If false, appends the new entry to the history stack. | ||
/// </summary> | ||
public bool ReplaceHistoryEntry { get; init; } | ||
} |
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.
In an earlier edition of this PR, NavigationOptions
was a flags enum. I've changed it to a full-fledged struct
because I don't want to get into this situation again in the future where we need to add some other option and have to multiply out the number of overloads and obscure rules for what methods you have to implement in subclasses.
With a struct, even if we need new options of type string
, or rules about which combinations of options are legal to use simultaneously, it should be possible to model that (e.g., as different constructor overloads).
@@ -2,6 +2,8 @@ | |||
*REMOVED*static Microsoft.AspNetCore.Components.ParameterView.FromDictionary(System.Collections.Generic.IDictionary<string!, object!>! parameters) -> Microsoft.AspNetCore.Components.ParameterView | |||
*REMOVED*virtual Microsoft.AspNetCore.Components.RenderTree.Renderer.DispatchEventAsync(ulong eventHandlerId, Microsoft.AspNetCore.Components.RenderTree.EventFieldInfo! fieldInfo, System.EventArgs! eventArgs) -> System.Threading.Tasks.Task! | |||
*REMOVED*readonly Microsoft.AspNetCore.Components.RenderTree.RenderTreeEdit.RemovedAttributeName -> string! | |||
*REMOVED*Microsoft.AspNetCore.Components.NavigationManager.NavigateTo(string! uri, bool forceLoad = false) -> void | |||
*REMOVED*abstract Microsoft.AspNetCore.Components.NavigationManager.NavigateToCore(string! uri, bool forceLoad) -> void |
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.
Although these show as removed, there should be no back-compat loss (source or binary) because of adding new equivalents. I think our PublicAPI tooling doesn't reflect some details about how adding new optional params.
But if you're code-reviewing this, please check you agree with my claim here :)
@@ -29,6 +31,15 @@ Microsoft.AspNetCore.Components.Lifetime.ComponentApplicationLifetime.State.get | |||
Microsoft.AspNetCore.Components.Lifetime.IComponentApplicationStateStore | |||
Microsoft.AspNetCore.Components.Lifetime.IComponentApplicationStateStore.GetPersistedStateAsync() -> System.Threading.Tasks.Task<System.Collections.Generic.IDictionary<string!, byte[]!>!>! | |||
Microsoft.AspNetCore.Components.Lifetime.IComponentApplicationStateStore.PersistStateAsync(System.Collections.Generic.IReadOnlyDictionary<string!, byte[]!>! state) -> System.Threading.Tasks.Task! | |||
Microsoft.AspNetCore.Components.NavigationManager.NavigateTo(string! uri, Microsoft.AspNetCore.Components.NavigationOptions options) -> void | |||
Microsoft.AspNetCore.Components.NavigationManager.NavigateTo(string! uri, bool forceLoad = false, bool replace = false) -> void |
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.
Do we need this overload?
I think we should force people into using the navigation options directly and set ourselves for success in the future.
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.
Personally I find:
navManager.NavigateTo("something", replace: true);
to be a lot more readable than:
navManager.NavigateTo("something", new NavigationOptions { ReplaceHistoryEntry = true });
However I understand it's always a subjective balance when we consider adding overloads just for convenience. It depends on how universal we think the convenience-overload pattern will be, and whether it will stand the test of time as being the only extra convenience we need, vs something that ends up getting multiplied out into many other overload variants. (I know you know this; just giving context for anyone else reading)
We do need at least to keep the NavigateTo(string, bool)
overload for back-compat. To me it felt a bit rough if this other equally-often-used flag was not available in a similar shorthand format.
Shall we leave a final call on this until we get to API review, or do you feel strongly now?
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.
I don't feel strongly about it, it was mainly a suggestion.
// For back-compat, we need to accept multiple overloads | ||
export function navigateTo(uri: string, options: NavigationOptions): void; | ||
export function navigateTo(uri: string, forceLoad: boolean): void; | ||
export function navigateTo(uri: string, forceLoad: boolean, replace: boolean): void; | ||
export function navigateTo(uri: string, forceLoadOrOptions: NavigationOptions | boolean, replaceIfUsingOldOverload: boolean = false) { |
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.
I haven't seen this used in a while in TS 😄.
I believe navigateTo
ends up in our internal namespace. The only thing that uses that overload is the auth bits in one place. I'm happy if you update those and avoid having to deal with the special case here, since we can consider this API internal and for our consumption, akin to private reflection.
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.
It's actually not within internal, however it's here
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.
Blazor.navigateTo
(the JS API) is very much public and supported. It's the only way to trigger a client-side Blazor navigation from JS code, so is certainly needed.
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.
Yeah, I saw that later. If you want to update the auth package as part of this change to rely on that, It would be nice.
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.
Looks great!
0fd0c05
to
9ee3402
Compare
/azp run |
Azure Pipelines successfully started running 2 pipeline(s). |
…igateTo So instead of pushing the new uri into the browser history, we replace the uri in the browser history
Modified NavigateTo be source and binary compatible with previous versions See: to https://github.com/dotnet/roslyn/blob/master/docs/Adding%20Optional%20Parameters%20in%20Public%20API.md
!!!IMPORTANT!!!! I have also added a pragma to disable a warning which should NOT be disabled. It's only added to get it reviewed and fixed. #pragma warning disable RS0027 // Public API with optional parameter(s) should have the most parameters amongst its public overloads. Is added to the NavigationManager Before merging this should be addressed.
The forceLoad flag would be ignored if not loading the same Uri
7a18e65
to
4fb201b
Compare
1adc8cd
to
a68395e
Compare
This is a continuation of the work at #25752
It's a surprisingly involved change for what seems like just adding an extra bool flag. Mainly this is because it happens to be on one of the extensibility seams so we have to work hard to ensure it's nonbreaking for existing
NavigationManager
subclasses (e.g., that people have made for tests).The approach taken here is:
NavigateTo(string, bool=false)
will continue to work, because of carefully adding a combination of overloads that retains both source and binary compatibilityNavigationManager
subclasses that overrideabstract void NavigateToCore(string, bool)
will continue to work because the framework continues to call that as much as it can (i.e., whenever the caller doesn't specifyreplace=true
).NavigationManager
subclasses no longer need to overrideabstract void NavigateToCore(string, bool)
- they can do if they want, but instead, it's sufficient to overridevirtual void NavigateToCore(string, NavigationOptions)
since the new base class implementation of(string, bool)
calls into it.There is also a bunch of refactoring on the JS side because even though the previous code had both
force
andreplace
flags, it actually didn't support them both being true at the same time. Supporting this extra case made the existing code hard to read so I've restructured it for simplicity. AFAIK this should not result in any back-compat loss, even in extreme edge cases of unrecognized URL formats, because of retaining the distinction betweenurl
andabsoluteUrl
in the code paths.