Description
Describe the bug 🐞
I'm using Maui Hybrid on Windows. I'm using both Maui native views and some Blazor views, too. I've got a ReactiveUI.Maui.RoutedViewHost
to control the navigation via native views. I have some code that runs on startup that checks for a login status and changes the start page based on that:
d2lService.HasAccess.ObserveOn(RxApp.MainThreadScheduler).Subscribe(async x =>
{
if (x)
{
Router
.NavigateAndReset
.Execute(new RootViewModel())
.Subscribe();
}
else
{
Router
.NavigateAndReset
.Execute(new WebViewViewModel())
.Subscribe();
}
});
This part works just fine. If my token is no longer valid, my HasAccess
observable will return false and the app will start with a page that contains a WebView. If I do have access, the start page is a page that contains more complicated stuff.
What doesn't work is the transition between the two. When I "log in" via the webview page and then the HasAccess
observable flips, the viewmodel changes but the view stays the same. i.e. I now have a RootViewModel
in the stack, but the view is still for the WebViewViewModel
.
Step to reproduce
Create an AppBootstrapper.cs containing this:
internal class AppBootstrapper : ReactiveObject, IScreen
{
//private static required IDisposable _d;
public RoutingState Router { get; protected set; }
public BehaviorSubject<bool> HasAccess = new BehaviorSubject<bool>(false);
public AppBootstrapper()
{
Router = new RoutingState();
Locator.CurrentMutable.RegisterConstant(this, typeof(IScreen));
Locator.CurrentMutable.Register(() => new WebViewView(), typeof(IViewFor<WebViewViewModel>)); // webview for logging in
Locator.CurrentMutable.Register(()=> new RootPage(), typeof(IViewFor<RootViewModel>)); // root page
Observable.Timer(TimeSpan.FromSeconds(20)).Subscribe(x=> HasAccess.OnNext(true));
HasAccess.ObserveOn(RxApp.MainThreadScheduler).Subscribe(async x =>
{
if (x)
{
Router
.NavigateAndReset
.Execute(new RootViewModel())
.Subscribe();
}
else
{
Router
.NavigateAndReset
.Execute(new WebViewViewModel())
.Subscribe();
}
});
}
public static ReactiveUI.Maui.RoutedViewHost CreateMainPage(RoutingState router)
{
var host = new ReactiveUI.Maui.RoutedViewHost();
host.Router = router;
return host;
}
}
You'll then have to create two pages (ReactiveContentPage
) and viewmodels that implement IRoutableViewModel
. The page should start with one, then the timer should try to reset navigation to the new page.
Reproduction repository
https://github.com/reactiveui/ReactiveUI
Expected behavior
You should see two different pages with an interval of 20 seconds between them.
Screenshots 🖼️
No response
IDE
No response
Operating system
Windows
Version
11 latest non-dev
Device
No response
ReactiveUI Version
20.1.63
Additional information ℹ️
No response