2010-10-29 124 views
6

我想知道如果這是一個好主意或不好,在ViewModel中放置像列表的國家,以綁定到下拉列表?例如在網站的註冊頁面上。什麼是ViewModel的最佳做法

我的印象是ViewModel應該代表填充表單的一個實例,但我認爲我可能是錯的,因爲我已經看到其他人在ViewModel中放置了列表等東西。

將它放在靜態類中並直接從視圖中調用會不會更好?

Like CommonData.ListCountries();然後使用Lambda直接轉換爲視圖中的SelectList項列表?

回答

9

正如你已經意識到有很多方法來實現你的目標。雖然MVC design pattern鼓勵某些應用程序組織如何組織模型,但視圖和控制器最終是一個偏好問題。

Scott Allen討論了他在一篇博文中處理ASP.NET MVC drop down lists的偏好。 Scott使用擴展方法將複雜類型的枚舉轉換爲模型上的IEnumerable<SelectListItem>。然後他描述了在發回ASP.NET MVC時,他不會返回他發送給視圖的IEnumerable<SelectListItem>,而只是用戶選擇的值。他然後建議使用兩個模型可以簡化事情。

這是我稱之爲ViewModels和FormModels的合理描述。 ViewModel將顯示數據傳送到視圖,FormModel用於將收集的數據傳回控制器動作。進一步解釋:

  • ViewModels包含有助於渲染視圖的數據。通過以這種方式組織我的ViewModel,我可以放置所有必要的信息以將特定的視圖渲染到關聯的模型中。這可以防止我不得不使用ViewData來處理任何不是真正暫時的事情。
  • FormModels用於收集用戶輸入。 FormModels(幾乎)從不包含對其他複雜類型的引用,並且由基元,日期時間和字符串組成。

在任何一種情況下,我都有一個硬性規定,以never reuse a model for a different view。讓模型與用於呈現它們的視圖緊密結合使您的視圖更容易編寫。您不必擔心靜態方法之類的事情,因爲您的模型應該以易於渲染的形式將數據攜帶到相關的視圖中。諸如AutoMapper之類的工具可以幫助將域對象「拼合」成爲用於顯示目的的模型。

有關更多閱讀結賬:ASP.NET MVC terminology is tripping me up - why 'ViewModel'?

+0

感謝您的解釋。但是,如果我不使用AJAX,在窗體上顯示錯誤並重新綁定下拉列表的最簡潔的方式是什麼?我無法真正創建視圖模型的新實例,因爲它包含部分填充的表單,但我仍需要重新創建第二次返回視圖的國家/地區列表。 – lahsrah 2010-10-31 21:32:16

+0

lahsrah:我爲viewmodel創建了.populate()方法,我從控制器調用該方法,並且僅填充下拉菜單,其他屬性從表單提交中保留 – Muflix 2016-07-31 17:05:27

3

無論您的View需要什麼數據,都將其放入ViewModel中。

我看到它的方式,一旦你的視圖正在經歷渲染過程,它應該從它綁定的模型中獲得它需要的所有信息。

如果您開始使用幫助器方法,那麼視圖在某種意義上是「回到控制器」。擴展/輔助方法適用於格式化等,,但不應通過型號調用。不要忘了,你也有ViewData(基本上是HttpContext.Current.Items,爲單個請求而存在),這是一個輕量級的存儲機制,可用於跨部分視圖共享數據(例如)。

+0

好了,讓我怎麼處理這種情況存在驗證錯誤,表單和視圖模型需要傳遞迴原來的動作,以顯示parially填寫的表格的情況下,我將需要從數據庫中再次獲取列表。在這種情況下,在視圖模型上添加一個Populate方法以重新填充這些下拉列表,然後再將其傳回視圖,因此我不在兩個位置填充下拉列表是一個好主意? – lahsrah 2010-10-29 04:36:29

+2

不,這不是一個好主意。 ViewModel應該是簡單的存儲機制來保存數據,而不是檢索它。它應該只有屬性(一般來說)。請記住,這不是Web窗體。沒有ViewState,你的請求應該是無狀態的。如果您在提交表單後再次需要一些數據,請「再次獲取」,並將值設置到ViewModel中。驗證錯誤應該由模型狀態來處理。看看www.asp.net/mvc – RPM1984 2010-10-29 04:58:43

+0

上的一些vids/tutorials甚至比重新獲取數據更好的是做AJAX表單文章,並讓客戶端(例如Javascript)決定在成功或錯誤消息之後重定向頁面的位置返回。 – Ryan 2010-10-29 05:04:27

相關問題