【问题标题】:MvvmCross url navigation navigates to wrong ViewModelMvvmCross url 导航导航到错误的 ViewModel
【发布时间】:2018-02-01 12:46:36
【问题描述】:

我正在开发一个将 Xamarin Classis UI 与 MvvmCross 5.6.x 结合使用的移动应用程序,我们希望利用 url 基础导航向应用程序添加深度链接。我们希望遵循与客户网站相同的 url 方案,以便可以共享 url 以导航到两者中的特定内容。例如,以下两个 url 应该按照描述进行导航:

http://www.rseg.net/rewards 应该导航到忠诚度奖励列表 http://www.rseg.net/rewards/1234 应该显示特定奖励的详细信息

我已将以下两个视图模型设置为 url 的目标:

[assembly: MvxNavigation(typeof(RewardsViewModel),
    @"http://www.rseg.net/rewards")]
namespace MvvmNav.Core.ViewModels
{
    public class RewardsViewModel : MvxViewModel
    {
       …
    }
}

和

[assembly: MvxNavigation(typeof(RewardDetailViewModel),
    @"http://www.rseg.net/rewards/(?<id>[0-9]{4})$")]
namespace MvvmNav.Core.ViewModels
{
    public class RewardDetailViewModel :
        MvxViewModel<RewardDetailViewModel.Parameteres>
    {
        …
    }
}

我在初始视图模型中添加了以下两个命令。

public IMvxAsyncCommand ShowRewardsByUrl { get; protected set; }
protected async Task ShowRewardsByUrlHandler()
{
    var url = "http://www.rseg.net/rewards";

    if (await _navigationService.CanNavigate(url))
        await _navigationService.Navigate(url);
}

public IMvxAsyncCommand ShowRewardDetailByUrl { get; protected set; }
protected async Task ShowRewardDetailByUrlHandler()
{
    var url = "http://www.rseg.net/rewards/1234";

    if (await _navigationService.CanNavigate(url))
        await _navigationService.Navigate(url);
}

我看到的行为是两个命令最终都导航到 RewardsViewModel,而不是第二个命令导航到 RewwardDetailViewModel;有没有办法指定导航 url,以便我可以实现我上面描述的行为?

整个例子可以从GitHub下载https://github.com/rsegtx/So.MvvmNav;我只完成了 Android 应用的视图。

提前致谢。

【问题讨论】:

    标签: xamarin.ios xamarin.android mvvmcross


    【解决方案1】:

    我认为您需要一个 Navigation facade 才能工作并将两个 ViewModel 的路由也更改为 @"http://www.rseg.net/rewards(/(?&lt;id&gt;[0-9]{4}))?$":

    [assembly: MvxRouting(typeof(SimpleNavigationFacade), @"http://www.rseg.net/rewards(/(?<id>[0-9]{4}))?$")]
    namespace *.NavigationFacades
    {
        public class SimpleNavigationFacade
            : IMvxNavigationFacade
        {
            public Task<MvxViewModelRequest> BuildViewModelRequest(string url,
                IDictionary<string, string> currentParameters, MvxRequestedBy requestedBy)
            {
                var viewModelType = typeof(RewardsViewModel);
                if(currentParameters.TryGetValue("id", out string paramId) && !string.IsNullOrEmpty(paramId))
                    viewModelType = typeof(RewardDetailViewModel);
    
                return Task.FromResult(new MvxViewModelRequest(viewModelType, string.IsNullOrEmpty(paramId) ? new MvxBundle() : new MvxBundle(currentParameters), null));
            }
        }
    }
    

    嗨

    【讨论】:

    • 感谢样品;我得出了同样的结论,并且对我的概念证明应用程序有用。我希望有一种方法可以避免使用外观,但实际上它允许我复杂的路由逻辑,所以无论如何我可能已经结束了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多