MvvmCross IMvxNavigationFacade,MvxViewModelRequest 导致调用 Init() 而不是 Prepare()
MvvmCross IMvxNavigationFacade, MvxViewModelRequest causes Init() to be called rather than Prepare()
我在我的 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 传入参数 class 的实例,从而导致调用 Prepare() 方法?
整个解决方案可以在GitHubhttps://github.com/rsegtx/So.MvvmNav2
上查看
提前致谢!
经过一些研究后,我至少找到了一种方法来完成此任务。
创建一个 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 上更新了原始示例。
我在我的 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 传入参数 class 的实例,从而导致调用 Prepare() 方法?
整个解决方案可以在GitHubhttps://github.com/rsegtx/So.MvvmNav2
上查看提前致谢!
经过一些研究后,我至少找到了一种方法来完成此任务。 创建一个 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 上更新了原始示例。