Skip to content

Commit

Permalink
Do not use Shell for URI navigation (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dreamescaper authored Mar 26, 2023
1 parent 46242c6 commit 27a7433
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,35 +7,25 @@ namespace BlazorBindings.Maui;

public partial class Navigation
{
private readonly Dictionary<string, MBBRouteFactory> RouteFactories = new();
private readonly Dictionary<Type, StructuredRouteResult> NavigationParameters = new();
private List<StructuredRoute> Routes;

/// <summary>
/// Performs URI-based Shell navigation. This method is only available for Shell-based applications.
/// Performs URI-based navigation.
/// </summary>
/// <param name="uri">URI to navigate to.</param>
/// <param name="parameters">Additional parameters to set for component.</param>
public async Task NavigateToAsync(string uri, Dictionary<string, object> parameters = null)
{
ArgumentNullException.ThrowIfNull(uri);

var shell = MC.Shell.Current
?? throw new InvalidOperationException("URI-based navigation requires Shell-based application.");

Routes ??= FindRoutes();

var route = StructuredRoute.FindBestMatch(uri, Routes, parameters);

if (route != null)
{
NavigationParameters[route.Route.Type] = route;
if (!RouteFactories.TryGetValue(route.Route.BaseUri, out var routeFactory))
{
throw new InvalidOperationException($"A route factory for URI '{uri}' could not be found.");
}
await routeFactory.CreateAsync();
await shell.GoToAsync(route.Route.BaseUri);
var pars = GetParameters(route);
await Navigate(route.Route.Type, pars, NavigationTarget.Navigation, true);
}
else
{
Expand Down Expand Up @@ -67,13 +57,8 @@ private List<StructuredRoute> FindRoutes()

var structuredRoute = new StructuredRoute(route.Template, page);

//Register with XamarinForms so it can handle Navigation.
var routeFactory = new MBBRouteFactory(page, BuildPage);
MC.Routing.RegisterRoute(structuredRoute.BaseUri, routeFactory);

//Also register route in our own list for setting parameters and tracking if it is registered;
result.Add(structuredRoute);
RouteFactories[structuredRoute.BaseUri] = routeFactory;
}
}

Expand Down Expand Up @@ -103,11 +88,9 @@ private static Dictionary<string, object> ConvertParameters(Type componentType,
return convertedParameters;
}

private Task<MC.Page> BuildPage(Type componentType)
private Dictionary<string, object> GetParameters(StructuredRouteResult route)
{
var route = NavigationParameters[componentType];

var parameters = ConvertParameters(componentType, route.PathParameters);
var parameters = ConvertParameters(route.Route.Type, route.PathParameters);

if (route.AdditionalParameters is not null)
{
Expand All @@ -124,6 +107,6 @@ private static Dictionary<string, object> ConvertParameters(Type componentType,
}
}

return BuildElement<MC.Page>(componentType, parameters);
return parameters;
}
}
49 changes: 0 additions & 49 deletions src/BlazorBindings.Maui/Navigation/Shell/MBBRouteFactory.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<ContentPage Title="Test">
@page "/page-with-cascading-param"

<ContentPage Title="Test">
<VerticalStackLayout>
<Label>@Par1</Label>
<NonPageContent />
Expand Down
8 changes: 5 additions & 3 deletions src/BlazorBindings.UnitTests/Components/SwitchablePages.razor
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
@if (_switch)
@page "/switchable-pages"

@if (_switch)
{
<ContentPage Title="Page1">
<Button OnClick="Switch" />
Expand All @@ -12,6 +14,6 @@ else
}

@code {
bool _switch = true;
void Switch() => _switch = !_switch;
bool _switch = true;
void Switch() => _switch = !_switch;
}
35 changes: 35 additions & 0 deletions src/BlazorBindings.UnitTests/Navigation/ShellNavigationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,39 @@ public async Task ComponentShouldBeDisposedOnPopAsync()

Assert.That(isDisposed);
}

[Test]
public async Task NavigatedComponentShouldBeAbleToReplacePage()
{
await _navigationService.NavigateToAsync("/switchable-pages");
var navigatedPage = _mauiNavigation.NavigationStack.Last();

Assert.That(_mauiNavigation.NavigationStack.Count, Is.EqualTo(2));
Assert.That(navigatedPage.Title, Is.EqualTo("Page1"));

var switchButton = (MC.Button)((MC.ContentPage)navigatedPage).Content;
switchButton.SendClicked();
navigatedPage = _mauiNavigation.NavigationStack.Last();

Assert.That(_mauiNavigation.NavigationStack.Count, Is.EqualTo(2));
Assert.That(navigatedPage.Title, Is.EqualTo("Page2"));

switchButton = (MC.Button)((MC.ContentPage)navigatedPage).Content;
switchButton.SendClicked();
navigatedPage = _mauiNavigation.NavigationStack.Last();

Assert.That(_mauiNavigation.NavigationStack.Count, Is.EqualTo(2));
Assert.That(navigatedPage.Title, Is.EqualTo("Page1"));
}

[Test]
public async Task PushPageWithRootWrapper()
{
_navigationService.SetWrapperComponentType(typeof(WrapperWithCascadingValue));

await _navigationService.NavigateToAsync("/page-with-cascading-param");
var navigatedPage = _mauiNavigation.NavigationStack.Last();

PageContentWithCascadingParameter.ValidateContent(navigatedPage, WrapperWithCascadingValue.Value);
}
}

0 comments on commit 27a7433

Please sign in to comment.