2012-01-10 43 views
2

我们有其他视图模型在其中的视图模型。例如,我在几乎所有其他视图模型下都有一个导航视图模型,因为每个屏幕都有导航。建立导航视图模型的逻辑是在一个地方。验证失败后重新生成嵌套视图模型

问题在于,引用类型(如视图模型)在POST过程中是空的。这是有道理的,但这意味着如果我们需要再次返回视图,比如验证失败时,我们必须重建视图模型。我们不能只从头开始重建视图模型,因为它们保存了部分输入的数据。

现在,我们手动检查ModelState.IsValid并手动重建每个子视图模型。我们通过创建构建视图模型的Builders类型来消除重复逻辑。这些构建器目前有三种构建方法:一种构建空白视图模型,一种用于处理验证问题,另一种用于处理编辑。

ViewModel Build(<params>) // create 
void Build(ViewModel, <params>) // validation error 
ViewModel Build(DBObject, <params>) // edit 

这似乎是主要的矫枉过正。 90%的时间,如果一个属性是另一个视图模型,它应该被重建。如果存在将视图模型映射到构建器类的第三方库,则只需根据需要构建它们就会很好。这当然是递归的,并且也可以构建子视图模型。相反的:

return View(viewModel) 

return RedirectToAction("index", "home", viewModel) 

有,简直是像助手:

return View<ViewModel>() 

return RedirectToAction<ViewModel>("index", "home") 

回答

3

举例来说,我有一个导航由于每个屏幕都有导航,因此几乎每个 其他视图模型都可以查看模型。构建导航视图模型的 的逻辑集中在一个地方。

这似乎是一个很好的候选人,用于分割视图模型并使用Html.Action helper从独立的子动作呈现导航菜单。

这样你不必再担心主要操作和视图模型。

这样的想法是,你可以有负责生成菜单的菜单控制:

​​

那么相应的索引视图,这将是一个仅包含菜单的标记部分:

@model MenuViewModel 
@{ 
    Layout = null; 
} 
<ul> 
    <li>.... 
    <li>.... 
</ul> 

,然后您可以在您的_Layout内定义的位置渲染菜单:

@Html.Action("index", "menu") 

然后,您可以拥有与此菜单渲染完全分离的控制器和视图模型。

+0

我一直沿着RenderPartial方法走下去。这会涉及多个命中到服务器,每个子视图一个? – 2012-01-10 19:57:11

+0

@TravisParks,RenderPartial的缺点是您不会通过单独的控制器操作来获取菜单。子操作不涉及其他客户端请求。当你做'Html.Action'时,没有其他请求到你的服务器。整个客户端请求通过单个HTTP请求提供,并将结果汇​​总到发送给客户端的单个HTML中。 – 2012-01-10 20:00:30

+0

这种方法唯一的缺点是,如果需要多次,它可能会导致相同信息两次敲击DB。我正在考虑将用户信息存储在缓存中,以节省抓取时间。 – 2012-01-10 20:41:48