MvvmCross ShowViewModel加载序列

时间:2016-07-28 10:02:54

标签: c# xamarin viewmodel mvvmcross

我的ViewModel中存在一个排序问题,这似乎与线程相关,但我无法确定我们的错误或我的修复方式#34;正在修理它。

我有一个ViewModel需要调用异步方法来加载其初始数据。我正在调用MvvmCross自动调用的Init方法的异步方法。如果由于任何原因加载失败我想显示错误屏幕,但在Init调用的方法内调用ShowViewModel不会产生预期的结果。 ShowViewModel被正确调用,但是在调试器中跟随它后,看起来ErrorViewModel在原始ViewModel / View完成加载之前显示 - 因此它加载但不会出现,因为它被原始ViewModel覆盖。

这是加载代码的简化版本:

public async Task Init()
{
    await LoadInitialDataAsync();
}

protected async Task LoadInitialDataAsync()
{
    var loadResult = await LoadSomeStuffAsync();
    if (loadResult.IsBadNews)
    {
        ShowViewModel<ErrorViewModel>();
        return;
    }
}

MvxTrace日志告诉我在初始ViewModel上调用ShowViewModel之后立即调用ShowViewModel,但只显示初始View,而不是ErrorView。

To&#34; fix&#34;我可以做两件事之一。

我可以在Task.Run中包装对LoadInitialDataAsync的调用:

await Task.Run(async () =>
{
    await LoadInitialDataAsync();
});

或者,我可以在内部ShowViewModel调用之前添加一个小延迟:

protected async Task LoadInitialDataAsync()
{
    var loadResult = await LoadSomeStuffAsync();
    if (loadResult.IsBadNews)
    {
        await Task.Delay(1);
        ShowViewModel<ErrorViewModel>();
        return;
    }
}

这些更改中的任何一个都会产生所需的结果 - 如果在加载期间发生了错误,则ErrorViewModel会显示其视图。

问题是,我不相信这个问题,因为我不了解谚语中出了什么问题,因此不知道这个问题有多强大。这似乎是一个随意的计时事物,将在最不方便的时候在未来的某个时刻再次破裂。

如果有人能够理解MvvmCross的内部结构,那么我很感激!

2 个答案:

答案 0 :(得分:3)

Init方法应该做的很少。 Init通常用于复制传递到ShowViewModel<TViewModel>()的一些导航参数。 Start方法是您打算进行ViewModel启动的方法,例如调用LoadInitialDataAsync。有关详细信息,请查看App Lifecycle documentation

答案 1 :(得分:0)

基于https://github.com/MvvmCross/MvvmCross/wiki/viewmodel--to-viewmodel-navigation

  

当您的应用显示ViewModel页面时,请说出FirstViewModel   第一页可以请求将显示向前移动到a   新的ViewModel页面,通过使用如下调用来说SecondViewModel:

ShowViewModel<SecondViewModel>();
     

当FirstViewModel发出此请求时,则为MvvmCross   框架将:

     
      
  • 找到一个视图,用作应用内SecondViewModel的“页面” - 通常这将是SecondView
  •   
  • 创建此SecondView的新实例
  •   
  • 创建SecondViewModel并将其作为新SecondView的DataContext提供
  •   
  • 要求操作系统显示SecondView
  •   

您的ShowViewModel<ErrorViewModel()被调用,而初始View尚未显示,这可能是它的问题,并且适合您的调试器行为。

延迟使得它可能有足够的时间显示并且异步任务没有阻止它,所以它显示,然后显示完成并切换到另一个视图。

一个选项可能会在使用ShowViewModel之前进行初始化并传递数据,尽管我没有这方面的经验。 或保存错误状态,让视图加载并从视图中调用viewmodel,让它在创建后切换。

虽然我不喜欢其中任何一个,这就是为什么我之前通过服务进行初始化,如果它在切换到新的viewmodel之前失败了。

Dunno你当前的结构有多复杂,最好的结果是什么。