构造函数视图模型 [英] Constructor in ViewModel

查看:145
本文介绍了构造函数视图模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能在视图模型构造,至极初始化数据服务?
(不要误会我的意思,我的数据服务访问数据存储的网络服务)像这样的东西(因为问我得到了ViewLoader抛出的异常无法加载视图模型......而且,不显示整个例外...):

Is it possible to have a constructor in the view model, wich initializes the data service? (Don't get me wrong, my data service is accessing the web-service of the data storage) Something like this (Asked because i get Exceptions thrown by the ViewLoader "Failed to load ViewModel..." And it doesn't show the whole Exception...):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Collections.ObjectModel;
    using Cirrious.MvvmCross.ViewModels;
    using Cirrious.MvvmCross.Commands;
    using MobSales.Logic.DataService;
    using MobSales.Logic.Base;
    using MobSales.Logic.Model;

    namespace MobSales.Logic.ViewModels
    {
        public class CustomersViewModel:MvxViewModel
        {
            ICustomerService custService;
        public CustomersViewModel(ICustomerService custService)
        {
            this.custService = custService;
            if (custService != null)
            {
                custService.LoadCustomerCompleted += new EventHandler<CustomerLoadedEventArgs>(custService_LoadCustomerCompleted);
            }
            loadCustomerCommand = new MvxRelayCommand(LoadCustomer);
            loadCustomerCommand.Execute();
        }


    private ObservableCollection<Customer> customers;

    public ObservableCollection<Customer> Customers
    {
        get { return customers; }
        set
        {
            customers = value;
            FirePropertyChanged("Customers");
        }
    }


    private CustomerViewModel customer;

    public CustomerViewModel Customer
    {
        get { return customer; }
        set
        {
            customer = value;
            FirePropertyChanged("Customer");
        }
    }


    private MvxRelayCommand loadCustomerCommand;

    public MvxRelayCommand LoadCustomerCommand
    {
        get { return loadCustomerCommand; }
    }

    public void LoadCustomer()
    {
        custService.LoadCustomer();
    }

    void custService_LoadCustomerCompleted(object sender, CustomerLoadedEventArgs e)
    {
        if (e.Error != null)
        {
            return;
        }

        List<Customer> loadedCustomers = new List<Customer>();
        foreach (var cust in e.Customers)
        {
            loadedCustomers.Add(new Customer(cust));
        }

        Customers = new ObservableCollection<Customer>(loadedCustomers);
    }

}



完整的例外是:Cirrious。 MvvmCross.Exceptions.MvxException:无法加载视图模型类型MobSales.Logic.ViewModels.CustomersViewModel从定位器MvxDefau ...

The full exception is: Cirrious.MvvmCross.Exceptions.MvxException: Failed to load ViewModel for type MobSales.Logic.ViewModels.CustomersViewModel from locator MvxDefau…

从视图视图模型的结合就像我实现张贴在这篇文章: MVVMCross绑定在Android中

The binding from View to ViewModel is realized like i've posted it in this post: MVVMCross Bindings in Android

谢谢!

推荐答案

一个MvvmCross的异常(自以为是)的特点是,默认情况下它使用视图模型构造参数作为导航机制的一部分。

One of the unusual (opinionated) features of MvvmCross is that by default it uses ViewModel constructor parameters as part of the navigation mechanism.

这是一个例子,我的回答解释的薪火从视图模型的变量到另一个视图(mVVMCross)

This is explained with an example in my answer to Passing on variables from ViewModel to another View (MVVMCross)

基本思路是,当一个HomeViewModel使用请求导航:

The basic idea is that when a HomeViewModel requests a navigation using:

private void DoSearch()
{
    RequestNavigate<TwitterViewModel>(new { searchTerm = SearchText });
}



那么这将导致与传递到构造函数的SEARCHTERM构建一个TwitterViewModel

then this will cause a TwitterViewModel to be constructed with the searchTerm passed into the constructor:

public TwitterViewModel(string searchTerm)
{
    StartSearch(searchTerm);
}



目前,这意味着每个视图模型必须有一个公共的构造函数其中有要么没有的参数或仅具有字符串参数

所以你的视图模型不加载原因是因为MvxDefaultViewModelLocator无法找到合适的构造您的视图模型。

So the reason your ViewModel isn't loading is because the MvxDefaultViewModelLocator can't find a suitable constructor for your ViewModel.

有关服务时,MvvmCross框架并提供一个简单的IoC容器可以是最容易IServiceType>()扩展方法使用 GetService的<访问。例如,在 Twitter的样品视图模型之一包括:

For "services", the MvvmCross framework does provide a simple ioc container which can be most easily accessed using the GetService<IServiceType>() extension methods. For example, in the Twitter sample one of the ViewModel contains:

public class TwitterViewModel
    : MvxViewModel
    , IMvxServiceConsumer<ITwitterSearchProvider>
{
    public TwitterViewModel(string searchTerm)
    {
        StartSearch(searchTerm);
    }

    private ITwitterSearchProvider TwitterSearchProvider
    {
        get { return this.GetService<ITwitterSearchProvider>(); }
    }

    private void StartSearch(string searchTerm)
    {
        if (IsSearching)
            return;

        IsSearching = true;
        TwitterSearchProvider.StartAsyncSearch(searchTerm, Success, Error);
    }

    // ...
}

同样,您可以看到会议服务数据是如何在的会议BaseViewModel

Similarly, you can see how the conference service data is consumed in the Conference BaseViewModel

如果您希望使用其他一些IoC容器或其他一些。建机制为您的ViewModels,那么你就可以覆盖在MvvmCross视图模型建设

If your preference is to use some other IoC container or some other construction mechanism for your ViewModels, then you can override the ViewModel construction within MvvmCross.

以获取有关如何做到这一点的想法来看看这个问题(和答案) - < A HREF =htt​​p://stackoverflow.com/questions/10411735/how-to-replace-mvxdefaultviewmodellocator-in-mvvmcross-application>如何更换MvxDefaultViewModelLocator在MVVMCross应用

Take a look at this question (and answers) for ideas on how to do this - How to replace MvxDefaultViewModelLocator in MVVMCross application

如如果你想的话,就应该很容易让你在调整这一问题的 MyViewModelLocator 例如与您的服务来构建你的视图模型。

e.g. if you want to, then it should be fairly easy for you to adjust the MyViewModelLocator example in that question to construct your ViewModel with your service.

这篇关于构造函数视图模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆