2012-02-22 110 views
0

我的問題與this one非常相似。我正在開發的應用程序是用MVC 3和Razor編寫的。它允許用戶從商店中選擇商品並將其發送到不同的地址。使用編輯器模板顯示多個表格

這裏是我的ViewModels:

public class DeliveryDetailsViewModel 
{ 
    public FromDetailsViewModel From { get; set; } 
    public IList<ToDetailsViewModel> To { get; set; } 
} 

public class DetailsViewModel 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Email { get; set; } 
} 

public class FromDetailsViewModel : DetailsViewModel 
{ 
    public string StreetAddress { get; set; } 
    public string Suburb { get; set; } 
    public string Postcode { get; set; } 
} 

public class ToDetailsViewModel : DetailsViewModel 
{ 
    public string Message { get; set; } 
} 

我的看法是類似以下。

@model Store.ViewModels.DeliveryDetailsViewModel 

@Html.EditorFor(m => m.From) 

@Html.EditorFor(m => m.To) 

我的本意是,形式(每放入購物車的項目之一)的集合將顯示,使用戶在輸入不同的交貨細節,每一個表格都有自己的提交按鈕。

這使得編輯模板, 「要」 的形式如下:

@model Store.ViewModels.ToDetailsViewModel 

@using (Html.BeginForm("ConfirmTo", "Delivery")) 
{ 
    @Html.TextBoxFor(m => m.FirstName) 
    @Html.TextBoxFor(m => m.LastName) 
    @Html.TextBoxFor(m => m.Email) 
    @Html.TextBoxFor(m => m.Message) 

    <input type="submit" value="Confirm" /> 
} 

我的控制器:

public class DeliveryController : Controller 
{ 
    public ActionResult Index() 
    { 
     var model = new DeliveryDetailsViewModel(); 
     model.From = new FromDetailsViewModel(); 
     model.To = new List<ToDetailsViewModel>(); 
     return View(model); 
    } 

    public ActionResult ConfirmTo(ToDetailsViewModel toDetails) 
    { 
     // Save to database. 
    } 
} 

我有幾個問題:

  1. 的「to」編輯器模板不會渲染任何內容(儘管它已經習慣了)。它指出模型類型不匹配(即,ToDetailsViewModelList<ToDetailsViewModel>不一樣),儘管我認爲編輯器模板應該將索引附加到輸入字段名稱以啓用適當的綁定。

  2. 單擊「確認」並提交「收件人」列表中的第一個表單時,控制器將使用正確的綁定接收視圖模型。提交以下任何形式(索引1或更大)將調用ConfirmTo操作並傳遞一個爲空的ToDetailsViewModel

任何幫助,將不勝感激,如果你想了解我有問題還是我使用的代碼的更多信息,請不要猶豫,問。

回答

1

1)「to」編輯器模板不是提交任何東西

在您的控制器操作中,您沒有在列表中放入任何東西。你剛剛實例化它。所以把一些元素:

model.To = new List<ToDetailsViewModel>(); 
model.To.Add(new ToDetailsViewModel()); 
model.To.Add(new ToDetailsViewModel()); 
... 

2)當點擊確認並提交第一個表單中列出的控制器接收與正確綁定視圖模型。提交以下任何形式(索引1或更大)將調用ConfirmTo操作並傳遞一個爲空的ToDetailsViewModel。

即使對於第一個元素,由於輸入字段當前沒有正確的名稱,所以我會感到驚訝。它們的前綴爲To[someIndex],而您的ConfirmTo需要平板模型,而不是集合。

所以,你可以讓正確的輸入元素在你的~/Views/Shared/EditorTemplates/ToDetailsViewModel.cshtml編輯模板生成的前綴設置爲空字符串:

@model ToDetailsViewModel 
@{ 
    ViewData.TemplateInfo.HtmlFieldPrefix = ""; 
} 
@using (Html.BeginForm("ConfirmTo", "Home")) 
{ 
    @Html.TextBoxFor(m => m.FirstName) 
    @Html.TextBoxFor(m => m.LastName) 
    @Html.TextBoxFor(m => m.Email) 
    @Html.TextBoxFor(m => m.Message) 

    <input type="submit" value="Confirm" /> 
} 
+0

感謝您的幫助達林,我的問題的第一部分已解決!關於輸入字段前綴,您提供的解決方案可以工作,但這意味着如果我返回視圖併爲其提供更新後的模型,則所有名字字段都會獲得我輸入的值,而不僅僅是一種形式I已編輯。 (我希望我表達自己的能力足以被理解。) – Geekatron 2012-02-22 22:40:26

+0

我通過使用RedirectToAction(「Index」)而不是返回View(「Index」,model)來解決問題。謝謝Darin! – Geekatron 2012-02-22 23:35:18

0

1)有你試試這個,因爲您的視圖模型

public IList<ToDetailsViewModel> To { get; set; } 

要爲一個列表,因此你的編輯模板應該有

@model IEnumerable<Store.ViewModels.ToDetailsViewModel> 

和模板應使用foreach

@foreach(model in Model){} 
+0

不幸的是我已經試過了,是的。由於「to」表單在頁面上多次出現,因此模型聯編程序會感到困惑,並使用提交的輸入填充所有「FirstName」字段。這是因爲每個表單的輸入名稱都是相同的。 – Geekatron 2012-02-22 05:55:37

+0

此外,將視圖模型列表傳遞給EditorFor()助手應該處理創建具有不同名稱的字段。例如:「To_0__FirstName」和「To_1__FirstName」。 – Geekatron 2012-02-22 05:58:45

+0

那麼如何使用提交按鈕只需使用並編寫一個jQuery來獲取信息並通過jQuery – Jayanga 2012-02-22 06:04:33

相關問題