2012-01-10 42 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