MVVM视图模型和异步数据初始化

时间:2012-12-16 16:27:44

标签: design-patterns windows-phone-8 mvvm windows-store-apps mvvm-light

我有一个带有需要服务的构造函数的视图模型。我正在使用GalaSoft的MvvmLight,它使用服务定位器将视图连接到视图模型。

SimpleIOC处理为viewmodels构造函数提供服务很好,但我不知何故需要使用来自数据源的数据填充我的viewmodel。我的Viewmodel看起来像这样: -

    public class MainPageViewModel : ViewModelBase
{
    private readonly GroupService _groupService;
    private readonly GroupFactory _groupFactory;
    private readonly ObservableCollection<GroupVM> _groupVms = new ObservableCollection<GroupVM>();


    public MainPageViewModel(Domain.Services.GroupService groupService, VMFactories.GroupFactory groupFactory)
    {
        _groupService = groupService;
        _groupFactory = groupFactory;
    }

    public async Task Init()
    {
        var groups = await _groupService.LoadGroups();
        foreach (var group in groups)
        {
            GroupVms.Add(_groupFactory.Create(group));
        }
    }

    public ObservableCollection<GroupVM> GroupVms { get { return _groupVms; } }
}

某种方式需要调用init方法,但我不知道如何最好地执行此操作?我可以想到三个选择: -

  1. 我只是在构造函数上调用Init,但没有等待它(我知道这真的很糟糕)
  2. 我在ViewModelLocator对象上调用Init,但由于我无法返回任务,我再次无法等待init
  3. 在视图的加载中,我将DataContext转换为某种IAsyncViewmodel并等待init方法。
  4. 我在之前的Windows 8商店项目中使用了选项3,但感觉不对。任何建议都会非常感激!

    由于

    罗斯

2 个答案:

答案 0 :(得分:7)

我很好奇为什么你认为不等待异步调用是一种不好的做法。在我看来,只要你知道这意味着什么,调用将在后台执行并且可能随时返回,这也不错。

通常我所做的是在构造函数中调用异步方法以用于设计时数据创建目的,我不等待它。我只需要在需要更新绑定的地方引发PropertyChanged和CollectionChanged事件,这样就可以解决问题。

干杯 劳伦

答案 1 :(得分:1)

我不像以前那样熟悉MvvmLight,但我试图以各种方式处理async构造函数。

选项(1)具有错误处理的复杂性。选项(3)强制InitAsync可以访问。

我更喜欢async工厂方法(例如,选项(2),其中DataContext将保持null,直到VM初始化完成),但听起来像{{1}不适用于此。所以(现在)你必须在不使用IoC的ViewModelLocator工厂和不理想的其他选项(1或3)之间进行选择。

就个人而言,我会抛弃IoC for VM / View绑定(我从不使用IoC;我的观点取决于我的VM)并使用async工厂方法。但是,如果您想继续使用IoC,其他选项是完全可行的。对于VM,我认为如果你的async方法总是有一个顶级try / catch,则选项(1)会比选项(3)略好。