简体   繁体   English

MVVM ViewModel异步数据初始化

[英]MVVM viewmodel async data initialization

I am trying to get familiar with Windows Store apps and the MVVM pattern (I'm new to this platform). 我正在尝试熟悉Windows应用商店应用程序和MVVM模式(我是这个平台的新手)。 I have a very simple app that parses a list of Person objects from a json file, then shows them in a gridView. 我有一个非常简单的应用程序,它可以从json文件中解析Person对象的列表,然后在gridView中显示它们。 I have created a PeopleViewModel class to serve as the view model for my mainpage, which handles the parsing, and exposes the array of objects for the view. 我创建了一个PeopleViewModel类作为主页的视图模型,该类负责解析并公开视图的对象数组。 The parsing method: 解析方法:

public async Task init()
{
    StorageFolder resourceFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
    resourceFolder = await resourceFolder.GetFolderAsync("Resources");

    StorageFile resourceFile = await resourceFolder.GetFileAsync("persons.json");
    string fileContent = await Windows.Storage.FileIO.ReadTextAsync(resourceFile);

    ObservableCollection<Person> persons = new ObservableCollection<Person>();

    JsonValue json = JsonValue.Parse(fileContent);
    int personCount = json.GetArray().Count;
    for (int i = 0; i < personCount; i++)
    {
        IJsonValue element = json.GetArray()[i];
        Person p = new Person(element);
        persons.Add(p);
    }

    _persons = persons;
}

Then in my XAML, I set this class as the data context of the page: 然后在我的XAML中,将此类设置为页面的数据上下文:

<!-- viewModel namespace defined above -->
<Page.DataContext>
    <viewModel:PeopleViewModel/>
</Page.DataContext>

Since reading a file is an async operation, I can't put it in the default constructor of PeopleViewModel, I have to call its init() method from the code-behind file of my xaml: 由于读取文件是异步操作,因此无法将其放入PeopleViewModel的默认构造函数中,因此必须从xaml的代码隐藏文件中调用其init()方法:

private async void navigationHelper_LoadState(object sender, LoadStateEventArgs e)
{
    PeopleViewModel viewModel = this.DataContext as PeopleViewModel;
    await viewModel.init();
}

My code is working well, but I'm wondering if this is the right way to do it. 我的代码运行良好,但是我想知道这是否是正确的方法。 Is there a way to initialize my viewmodel with an async method, and keep my code-behind file "clean" (or is this solution considered clean)? 有没有一种方法可以使用异步方法初始化我的视图模型,并使我的代码隐藏文件保持“干净”(或者此解决方案被认为是干净的)?

Sure there is, just call an async void method from the constructor (no await needed), which can in turn now call methods with await . 当然可以,只需从构造函数中调用async void方法(无需await ),该方法现在可以使用await调用方法。 (And yes, the best practice is to keep the codebehind clean.) (是的,最佳实践是保持后台代码干净。)

EDIT: 编辑:

So based on your experience I left out the part saying that you shouldn't really do this. 因此,根据您的经验,我遗漏了一部分,说您不应该这样做。 Instead set up something where an event notifies your viewmodel to load things. 而是在事件通知您的视图模型加载内容的地方进行设置。 Basically you should only use async void with event handlers. 基本上,您仅应将async void与事件处理程序一起使用。 More on this at the bottom of this page: http://caraulean.com/blog/2013/07/15/using-caliburn-micro-with-async-await/ (Although I prefer MVVMlight or PRISM - the latter even gives you the INavigationAware interface where you get your OnNavigatedTo events in you VM as well.) 本页底部的更多信息: http ://caraulean.com/blog/2013/07/15/using-caliburn-micro-with-async-await/(尽管我更喜欢MVVMlight或PRISM-后者甚至给出了您在INavigationAware界面中也可以在VM中获得OnNavigatedTo事件。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM