我是MVVM模式和Caliburn.Micro的新手。我已经阅读了一些关于如何入门的教程,但我对Caliburn环境中MVVM的Model
部分感到困惑。
我想创建我的第一个MVVM应用程序,我有一些设计问题:
我应该如何保留对一个复杂模型的许多实例的引用? 对于前者cumtomers(客户模型类的实例)
是否有可能操纵一个模型类 的ViewModels?我应该如何存储我的模型参考,所以它将是 从不同的ViewModels可见?
我应该将代码放在更复杂的模型manupulation /文件中, 数据库存储?我该如何调用这样的代码?我不是在这里问 关于SQLConnections,但MVVM最佳实践。 :)
提前感谢您的帮助:)
编辑:--------------------------------------------- ----------
谢谢你的回复。我更清楚地理解这个话题,但我仍然对某些细节感到困惑。
举个例子,让我们假设这个小应用程序。我有一个允许我添加新客户的表单。它有一些字段,如姓名,姓氏等。 按下按钮后,我在ViewModel中调用addCustomer命令。我希望我的程序将新创建的客户存储在数据库中。
我的视图还有List控件(无论如何),它将我的客户显示为原始字符串(例如"姓名:John,Surname:Doe,地址:..."我知道'愚蠢的让它像这样,但我需要一个模型操作的例子(如.toString()))
对于这个例子,我已经创建了一堆东西来说明我对这个过程的看法:
我认为有两种方法可以解决问题:
哪个更好?或者可能是另一种更适合MVVM的方法?
另一个问题是:我应该在哪里放置将从数据库中加载所有客户的方法,以便它们可以显示在列表中?在" get方法"在viewmodel里面,还是在模型类里面?
答案 0 :(得分:2)
在教程中,模型在ViewModel中显示为简单属性。 我该如何管理更复杂的模型?有没有命名 惯例?显然,应该有一些外部类 我的模型,但我应该如何在我的模型和模型之间进行通信 查看?
您的模型应代表它们所需的任何内容,无论是客户,帐户等。视图模型的工作是处理视图和模型之间的交互。
我应该如何保留对一个复杂模型的许多实例的引用? 对于前者cumtomers(Customer模型类的实例)
通常,您会将复杂模型映射到更友好的格式以供显示,您可以手动执行或使用AutoMapper之类的工具。
是否有可能操纵一个模型类 的ViewModels?我应该如何存储我的模型参考,以便它可见 来自不同的ViewModels?
如果您正在使用本地数据库,则可以传递ID。如果它是一项服务,您可以在本地保留模型,以供其他视图模型使用。您还可以将单例ISharedData注入需要使用共享数据的视图模型中。
我应该将代码放在更复杂的模型manupulation / file中, 数据库存储?我该如何调用这样的代码?我不是在这里问 关于SQLConnections,但MVVM最佳实践。 :)
为更复杂的模型操作/业务逻辑创建服务。将服务注入需要它们的视图模型中。 ICustomerService,IAccountService等
编辑:--------------------------------------------- ----------
你的第一个方法是正确的。关于共享模型是一个严重问题,因为保存方法绑定到视图模型类。视图模型将具有SaveCustomerCommand
,在单击按钮时会触发该SaveCustomerCommand
,因为它具有绑定。
CustomerModel
将保留CustomerModel
,无论_db.Save(CustomerModel)
如何保留。因此,如果它是一个数据库,那么视图模型可能会引用一个上下文并发出CustomerModel
。如果另一个视图模型需要操作CustomerService
,它将通过使用上下文来实现。视图模型还可以引用CustomerModel
来处理public class AddCustomerViewModel : Screen
{
private readonly ICustomerService _customerService;
public AddCustomerViewModel(ICustomerService customerService)
{
_customerService = customerService;
}
//If button is named x:Name="SaveCustomer" CM will
//bind it by convention to this method
public void SaveCustomer(Customer customer)
{
_customerService.Save(customer);
}
}
public class CustomerListViewModel : Screen
{
private readonly ICustomerService _customerService;
private List<CustomerDisplayModel> _customers;
public CustomerListViewModel(ICustomerService customerService)
{
_customerService = customerService;
}
public List<CustomerDisplayModel> Customers
{
get { return _customers; }
set
{
_customers = value;
NotifyOfPropertyChange();
}
}
//only fires once, unlike OnActivate()
protected override void OnInitialize()
{
var customers = _customerService.LoadAllCustomers();
//could just use the model but this shows how one might map from
//the domain model to a display model, AutoMapper could be used for this
Customers = customers.Select(c => new CustomerDisplayModel(c)).ToList();
}
}
public interface ICustomerService
{
List<Customer> LoadAllCustomers();
void Save(Customer customer);
}
//same as button, Label named x:Name="CustomerName" will bind
// to CustomerName
public class CustomerDisplayModel
{
private readonly Customer _customer;
public CustomerDisplayModel(Customer customer)
{
_customer = customer;
}
public string CustomerName
{
get { return _customer.Name; }
set { _customer.Name = value; }
}
public string Surname
{
get { return _customer.Surname; }
set { _customer.Surname = value; }
}
public string Address
{
get { return _customer.Address; }
set { _customer.Address = value; }
}
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Address { get; set; }
}
的crud。
以下是这可能的样子:
SELECT