Xamarin Forms 中的 Prism 导航用法 App.OnAppLinkRequestReceived
Prism navigation usage from Xamarin Forms App.OnAppLinkRequestReceived
我正在构建一个使用某些应用程序 link 的应用程序。在下面的示例中,我想在用户从电子邮件激活 link 时打开一个 ResetPasswordPage。
protected override async void OnInitialized()
{
InitializeComponent();
await NavigationService.NavigateAsync("/NavigationPage/LoginPage");
}
protected override void OnAppLinkRequestReceived(Uri uri)
{
if (uri.Host.EndsWith("site.nl", StringComparison.OrdinalIgnoreCase))
{
if (uri.AbsolutePath.StartsWith(@"/appname/resetpassword/"))
{
if (uri.Segments.Length == 4)
{
string resetCode = uri.Segments[3];
NavigationParameters param = new();
param.Add(NavConst.PasswordResetCode, resetCode);
await NavigationService.NavigateAsync("ResetPasswordPage", param);
}
}
}
}
此代码有效,但不是我所期望的(对于 iOS 和 Android)。我希望将 ResetPasswordPage 添加到在 OnInitialized 中设置的导航堆栈,以便它在导航栏中包含一个后退按钮,在这种情况下将用户带回登录页面。
但是,导航堆栈似乎被替换了。当显示 ResetPasswordPage 并且用户单击硬件后退按钮时,应用程序将关闭。但是,我希望它回到用户之前所在的位置。
我是否没有很好地理解某些导航概念,或者这可能是一个错误?
NavigationService 是 Prism 中针对 Xamarin.Forms 的一项相当独特的服务。它是为每个页面构建的新导航,导航堆栈取决于您从何处导航。
例如,当您从 MasterDetailPage / FlyoutPage 的上下文导航时,它会理解您并不是要在该页面顶部推送模式,而是从 Detail/Flyout 的上下文开始.如果 NavigationService 不断更新页面上下文,那么注入 MasterDetailPage/FlyoutPage 的 ViewModel 的导航服务将不知道它需要该页面作为导航的上下文。
您的问题最终是您从应用程序的上下文导航,该应用程序具有未设置页面的 NavigationService。因此,即使是相对导航仍将具有绝对导航的效果,从而重置 Application.MainPage,因为 NavigationService 不具有对另一个页面的上下文理解。
根据您的业务需求,您有几种不同的选择。一种是进行绝对导航,为您提供所需的导航堆栈。
您可能希望获取当前显示的页面并更新 NavigationService 以了解它。在应用程序 class 中,您可以添加如下内容:
protected override void OnAppLinkRequestReceived(Uri uri)
{
if (NavigationService is IPageAware pa)
{
page.Page = PageUtilities.GetCurrentPage(MainPage);
}
if (someCondition)
{
// This will now navigate from relatively from the page
// returned by GetCurrentPage.
NavigationService.NavigateAsync("SomeRelativeUrl")
.OnNavigationError(HandleNavigationError);
}
}
我正在构建一个使用某些应用程序 link 的应用程序。在下面的示例中,我想在用户从电子邮件激活 link 时打开一个 ResetPasswordPage。
protected override async void OnInitialized()
{
InitializeComponent();
await NavigationService.NavigateAsync("/NavigationPage/LoginPage");
}
protected override void OnAppLinkRequestReceived(Uri uri)
{
if (uri.Host.EndsWith("site.nl", StringComparison.OrdinalIgnoreCase))
{
if (uri.AbsolutePath.StartsWith(@"/appname/resetpassword/"))
{
if (uri.Segments.Length == 4)
{
string resetCode = uri.Segments[3];
NavigationParameters param = new();
param.Add(NavConst.PasswordResetCode, resetCode);
await NavigationService.NavigateAsync("ResetPasswordPage", param);
}
}
}
}
此代码有效,但不是我所期望的(对于 iOS 和 Android)。我希望将 ResetPasswordPage 添加到在 OnInitialized 中设置的导航堆栈,以便它在导航栏中包含一个后退按钮,在这种情况下将用户带回登录页面。
但是,导航堆栈似乎被替换了。当显示 ResetPasswordPage 并且用户单击硬件后退按钮时,应用程序将关闭。但是,我希望它回到用户之前所在的位置。
我是否没有很好地理解某些导航概念,或者这可能是一个错误?
NavigationService 是 Prism 中针对 Xamarin.Forms 的一项相当独特的服务。它是为每个页面构建的新导航,导航堆栈取决于您从何处导航。
例如,当您从 MasterDetailPage / FlyoutPage 的上下文导航时,它会理解您并不是要在该页面顶部推送模式,而是从 Detail/Flyout 的上下文开始.如果 NavigationService 不断更新页面上下文,那么注入 MasterDetailPage/FlyoutPage 的 ViewModel 的导航服务将不知道它需要该页面作为导航的上下文。
您的问题最终是您从应用程序的上下文导航,该应用程序具有未设置页面的 NavigationService。因此,即使是相对导航仍将具有绝对导航的效果,从而重置 Application.MainPage,因为 NavigationService 不具有对另一个页面的上下文理解。
根据您的业务需求,您有几种不同的选择。一种是进行绝对导航,为您提供所需的导航堆栈。
您可能希望获取当前显示的页面并更新 NavigationService 以了解它。在应用程序 class 中,您可以添加如下内容:
protected override void OnAppLinkRequestReceived(Uri uri)
{
if (NavigationService is IPageAware pa)
{
page.Page = PageUtilities.GetCurrentPage(MainPage);
}
if (someCondition)
{
// This will now navigate from relatively from the page
// returned by GetCurrentPage.
NavigationService.NavigateAsync("SomeRelativeUrl")
.OnNavigationError(HandleNavigationError);
}
}