我正在尝试了解如何在 MAUI 应用程序和 MVVM 的页面之间导航的最佳方式。
我在 Microsoft 的示例中看到,默认的操作方式是使用
PushAsync()
,但后来我发现可以使用 Shell.Current.GoToAsync()
进行导航。
两者有什么区别?或者说它们是互补的?
我创建了一个示例来测试
PushAsync()
和 GoToAsync()
。
GoToAsync()
根据路线在当前页面和目标页面之间导航。所以它不会创建同一页面的多个实例。一页只有一个实例。如果您使用 GoToAsync()
进行导航,例如 Page1 -> Page2,则无法使用 GoToAsync()
转到 Page1。您只能使用 GoToAsync("..")
前往第 1 页。
但是对于
PushAsync()
,您可以使用 PushAsync(new Page2())
创建同一页面的多个实例。导航堆栈将类似于 Page1 -> Page2 -> Page1 -> Page2...
所以
GoToAsync()
就像带有单例页面的 PushAsync()
一样。并且使用GoToAsync()
时需要注册路线。
此外,当您使用
GoToAsync()
进行导航时,还有一些限制,例如您可以将集合数据传递到下一页。但是当您使用PushAsync()
时,您可以将几乎所有类型的数据传递到目标页面。
总的来说,
PushAsync()
易于使用和传递数据,GoToAsync()
功能更好,但需要更多细节。
我认为 PushAsync() 不再可用于使用 Shell 进行导航,您应该使用 GotoAsync()。
但是 PushAsync 与将页面堆叠在其他页面上有关,以便您稍后可以弹出并导航回该页面。 GotoAsync() 使用亲戚来导航,您可以在此处查看文档:link
所以我也在测试这个,除了Liyun所说的之外,这就是我所经历的:
在 RowDetail.cs 中,我有一个按钮 backBtn 并尝试导航回路线 /SelectRow
backBtn.Clicked += async (sender, args) => await Shell.Current.GoToAsync("/SelectRow");
- 这工作得很好,但是导航很难找到它在导航堆栈中的位置,因此需要很长时间才能解决。如果您通过使用 GoToAsync 进入此页面 RowDetail 并再次使用它返回到另一条路线,则情况如此。
System.ArgumentException: 'unable to figure out route for: MyApp.Views.SelectRow (Parameter 'uri')'
- 如果您再次使用路由方法 GoToAsync 进行寻呼,并且错误地试图使用 GoToAsync 转到相同的路由,您将收到上面的错误消息。
上述错误的常见原因是由于路由重复注册。解决方案是不要在 AppShell.cs 和 AppShell.xaml.cs(或其他任何地方)中注册两次路由。在我的设置中,罪魁祸首是根页面、登录路由,并且它已在两个文件中注册。一旦我从全局路由中删除它(AppShell.xaml.cs-注册路由方法),它就可以正常工作。
这也必须是唯一的方法,因为它是根/父路由,因此它必须保留在 AppShell.xaml 中,以便应用程序能够正常启动到我想要的定义路由。
AppShell.xaml 定义如下:
<ShellContent Title="Login" ContentTemplate="{DataTemplate local:Login}" Route="Login" />