我有一个复杂的形式,具有视图模型的层次结构,我想知道如何构造代码,以便我的控制器不会包含所有操作的处理程序.
这是一个简化的例子:
使用相应的ViewModel:
public class MyPageViewModel
{
public List<TabViewModel> Tabs {get; set; }
public CustomerViewModel Customer;
}
public class TabViewModel
{
public string DisplayLabel { get; set; }
public bool Selected { get; set; }
}
class CustomerViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public List<Address> Addresses { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我知道如何在单独的组件中分离页面每个部分的渲染:我正在使用@Html.EditorFor并且@Html.DisplayFor对模型的每个部分都有一个单独的视图(由上图中的红色矩形表示).这很好用.ViewModel的一部分(例如TabViewModel类)也可以在其他页面上重复使用.
我遇到事件处理逻辑问题.可以在此页面上执行的操作很少(以蓝色背景表示).一种可能性是使用多个FORM标签 - 每个标签用于上图中的一个红色矩形.每个表单都有不同的操作URL,并由不同的控制器处理.但是当使用这种方法时,我可能会丢失相同的数据.例如:如果用户更改了First Name,然后点击Remove Address按钮,则First Name将不会被POST回服务器,并且更改将丢失.
这为我留下了整个页面的一个表单.这意味着所有操作都应由单个控制器类处理.我真的不喜欢这种方法,因为:
我已经阅读了Html.ActionFor,它可以让你从View中调用一个单独的控制器,但我认为这也不是好方法(它在渲染视图时发生,这是不正常的).
总而言之,这里又是一个问题:有没有办法处理从复杂视图模型的不同部分触发的动作/事件,以至于我不会在控制器中弄得一团糟?实际应用程序的最佳实践是什么(不是由Visual Studio脚手架生成的101个CRUD示例)
更新:请注意,这只是一个简化的示例 - 在现实中,视图模型要复杂得多,还有更多可以执行的操作.我问的是在ASP.NET MVC应用程序中构造控制器中的代码(或将其移动到单独的类)的一般方法.WebForms提供了用户控件,使我们能够封装View部件(ASCX)和事件处理程序.MVC有一个很好的封装视图的解决方案,我正在尝试找到构建逻辑/事件处理程序的正确方法.
我将为客户数据字段集添加一个“保存”按钮,并在用户单击“保存”按钮时保存/发布所有客户数据。这样,在您的编辑帖子操作中,您将只使用CustomerViewModel.
Address“添加新地址”和“删除此地址”将添加和删除使用 javascript所需的 html 。
“搜索现有客户”和“从外部数据库选择”可以显示一个弹出窗口,其中包含表单中相应部分所需的数据。使用Ajax来获取数据。
这样,您将拥有一个针对 CustomerData 字段集的简单编辑帖子操作、2 个用于在弹出窗口中显示数据的操作,以及一些用于操作地址部分的 javascript。