繁体   English   中英

ViewModel中的构造函数

[英]Constructor in ViewModel

是否可以在ViewModel中使用构造函数来初始化数据服务?

我的数据服务正在以类似于下面的方式访问数据存储的Web服务:

    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: Failed to load ViewModel for type MobSales.Logic.ViewModels.CustomersViewModel from locator MvxDefau…

从View到ViewModel的绑定实现如我在这篇文章中所示: Android中的MVVMCross Bindings

谢谢!

MvvmCross的一个不寻常的(固定的)功能是默认情况下它使用ViewModel构造函数参数作为导航机制的一部分。

这是我在回答将变量从ViewModel传递到另一个视图(MVVMCross)的一个例子中解释的

基本思想是当HomeViewModel使用以下命令进行导航时:

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

那么这将导致构建TwitterViewModel,并将searchTerm传递给构造函数:

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

目前,这意味着每个ViewModel必须具有公共构造函数,该构造函数没有参数或者只有字符串参数

因此,未加载ViewModel的原因是因为MvxDefaultViewModelLocator无法为ViewModel找到合适的构造函数。


对于“服务”,MvvmCross框架确实提供了一个简单的ioc容器,可以使用GetService<IServiceType>()扩展方法轻松访问它。 例如,在Twitter示例中,ViewModel中的一个包含:

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);
    }

    // ...
}

同样,您可以在Conference BaseViewModel中查看会议服务数据的使用情况


如果您的偏好是为ViewModel使用其他一些IoC容器或其他构造机制,那么您可以覆盖MvvmCross中的ViewModel构造。

看一下这个问题(和答案),了解如何做到这一点 - 如何在MVVMCross应用程序中替换MvxDefaultViewModelLocator

例如,如果您愿意,那么您应该很容易调整该问题中的MyViewModelLocator示例,以便使用您的服务构建ViewModel。

暂无
暂无

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

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