MvvmCross IMvxNavigationFacade,MvxViewModelRequest导致调用Init()而不是Prepare()

时间:2018-02-03 21:36:57

标签: mvvmcross

我已经在我的MvvmCross 5.6.x示例应用程序中实现了一个IMvxNavigationFacade用于深层链接。我在BuildViewModelRequest()中添加了逻辑来构造一个MvxViewModelRequest,其参数作为MvxBundle传入。

if (url.StartsWith("http://www.rseg.net/rewards/"))
{
    var parametersBundle = new MvxBundle();
    var id = url.Substring(url.LastIndexOf('/') + 1);
    parametersBundle.Data.Add("id", id);
    return Task.FromResult(
        new MvxViewModelRequest(typeof(RewardDetailViewModel),
        parametersBundle, null));
}

但是,这种方法会导致在目标ViewModel中调用旧式Init()方法,而不是新的类型安全Prepare()方法。

public class RewardDetailViewModel :
    MvxViewModel<RewardDetailViewModel.Parameteres>
{
    ...

    public new void Init(string id)
    {
        if (!string.IsNullOrWhiteSpace(id))
        {
            if (int.TryParse(id, out _rewardId))
                RaiseAllPropertiesChanged();
        }
    }

    public override void Prepare(Parameteres parameter)
    {
        if (parameter != null)
        {
            _rewardId = parameter.RewardId;
            RaiseAllPropertiesChanged();
        }
    }
}

有没有办法构造MvxViewModelRequest,以便为目标ViewModel传入参数类的实例,从而导致调用Prepare()方法?

可以在GitHub https://github.com/rsegtx/So.MvvmNav2

上查看整个解决方案

提前致谢!

1 个答案:

答案 0 :(得分:0)

在做了一些研究后,我发现了至少一种方法来实现这一目标。 创建一个ViewModelInstanceRequest而不是ViewModelRequest,以便您可以调用ViewModelLoader.LoadViewModel传入一个参数对象; ViewModelRequest仅允许使用MvxBundle传递参数。对NavigationFacade上的BuildViewModelRequest()进行以下更改:

var request = new
    MvxViewModelInstanceRequest(typeof(RewardDetailViewModel));
var parameters = new RewardDetailViewModel.Parameteres();

.... parse parameters and fill in parameters object

request.ViewModelInstance = ViewModelLoader.LoadViewModel(
    request, parameters, null);

return Task.FromResult((MvxViewModelRequest)request);

创建您自己的IMvxNavigationService并添加逻辑以检查从NavigationFacde返回的对象,如果它是ViewModelInstanceRequest,则按原样使用它,而不是先前创建的。

var facadeRequest = await facade.BuildViewModelRequest(path,
    paramDict).ConfigureAwait(false);

...     

if (facadeRequest is MvxViewModelInstanceRequest)
    request = facadeRequest as MvxViewModelInstanceRequest;
else
{
    facadeRequest.ViewModelType = facadeRequest.ViewModelType;
    if (facadeRequest.ParameterValues != null)
    {
        request.ParameterValues = facadeRequest.ParameterValues;
    }
    request.ViewModelInstance = ViewModelLoader.LoadViewModel(
        request, null);
}

我在GitHub https://github.com/rsegtx/So.MvvmNav2上更新了原始示例。