2012-02-22 76 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