2011-09-26 53 views
4

好的,經過一番研究,我無法理解「viewmodel事物」。如何使用ViewModel

我沒有找到任何文章解釋我使用ViewModels的步驟,與將實體作爲模型簡單傳遞給View相比。 當使用純實體時,它非常直接:

如果創建一個新條目,只顯示視圖。如果是發佈,驗證,請添加(x)和voilá!編輯時,填充對象並將其發送到視圖。發佈,驗證,更改狀態並保存。這裏沒有祕密。

但我無法創建和編輯ViewModels。有人可以幫助我嗎?

短,我有這樣的波蘇斯:

public class Vessel 
{ 
    public int Id { get; set; } 

    [Required] 
    public string Name { get; set; } 

    public int ShipownerId { get; set; } 
    public virtual Shipowner Shipowner { get; set; } 
} 

public class Shipowner 
{ 
    public int Id { get; set; } 

    public string Name { get; set; } 


    public virtual ICollection<Vessel> Vessels { get; set; } 
} 

這種觀點:

@model INTREPWEB.Models.VesselCreateViewModel 
@using (Html.BeginForm()) { 
@Html.ValidationSummary(true) 
    <fieldset> 
     <legend>Vessel</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Vessel.Name) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Vessel.Name) 
      @Html.ValidationMessageFor(model => model.Vessel.Name) 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownListFor(model => model.Vessel.ShipownerId, Model.Shipowners, String.Empty) 
      @Html.ValidationMessageFor(model => model.Vessel.Name) 
     </div> 

     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 

我創建這個視圖模型:

public class VesselCreateViewModel 
{ 
    public Vessel Vessel { get; set; } 

    public SelectList Shipowners { get; set; } 

    public VesselCreateViewModel() 
    { 
     using (INTREPDB db = new INTREPDB()) 
     { 
      var list = db.Shipowners.ToList() 
       .Select(x => new SelectListItem 
       { 
        Text = x.Name, 
        Value = x.Id.ToString() 
       }); 
      Shipowners = new SelectList(list, "Value", "Text"); 
     } 
    } 

    public VesselCreateViewModel(int id) 
    { 
     using (INTREPDB db = new INTREPDB()) 
     { 

      Vessel = db.Vessels.Find(id); 

      var list = db.Shipowners.ToList() 
       .Select(x => new SelectListItem 
       { 
        Text = x.Name, 
        Value = x.Id.ToString() 
       }); 
      Shipowners = new SelectList(list, "Value", "Text"); 
     } 
    } 
} 

正如你所看到的,它會自動填充View的集合以顯示DropDown菜單。通過與我僅使用模型相同的方式,我能夠創建新的血管。但編輯這個東西時弄不清楚我做錯了什麼。

這是錯誤的POST Edit方法:

[HttpPost] 
    public ActionResult Edit(VesselCreateViewModel vm) 
    { 
     if (ModelState.IsValid) 
     { 
      db.Entry(vm.Vessel).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(vm); 
    } 

我應該怎麼做,以挽救這個小怪物?

回答

1

正如你所看到的,你只是在這段代碼中使用ViewModel的模型部分。這是典型的恕我直言,所以你將ViewModel傳遞給視圖,但只在你的編輯回傳中綁定模型。

然後,如果必須,則可以根據更改後的模型輕鬆地重新創建視圖模型。

BTW:在這種情況下,IMO ViewModel是一個壞名字。如果我聽到ViewModel,我想到MVVM,但是這種情況下viewmodel只是某種靜態類型的View-Helper,應該沒有任何行爲。從史蒂夫senderson書

1

視圖模型小摘錄

MVC also uses the term view model, but refers to a simple model class that is used only to pass data from 
a controller to a view. We differentiate between view models and domain models, which are sophisticated 
representations of data, operations, and rules. 

如果你想保存視圖模型,你可以使用automapper

1

我猜你應該圍繞DB調用包裝在使用塊,就像在VesselCreateViewModel構造函數中。

您最終可能會在ViewModel中使用命令來保存,編輯或刪除數據,並將此命令綁定到視圖上的按鈕或其他控件。

我會推薦你​​關於MVVM的兩本很棒的書,你會發現很好的例子,也很容易理解它們。

構建企業應用程序與Windows Presentation Foundation中 和模型 - 視圖 - 視圖模型模式

臨WPF和Silverlight MVVM - 有效的應用程序開發與 模型 - 視圖 - 視圖模型

+0

我認爲視圖模型在mvc中有不同的背景 – Tassadaque

+0

是的,我相信你是對的我對mvc瞭解不多,而我只是剛開始使用MVVM。而我現在只看到它是asp.net-mvc的問題。 :)但是,那麼他不應該使用控制器? – BigL

+0

他的actionresult方法是在控制器中 – Tassadaque

相關問題