3

我有一个看起来像这样的模型:

商业
 - 分支  
   - 电话(*)
     - 电话类型  
     - 数字  
   - 营业时间 (*)     
     - 一周中的几天
     - 工作时间(*)
       - 从时间
       - 时间
 - 自定义字段 (*)
   - 姓名
   - 价值
 - 地址
   - 地址栏
   - 城市
   - 状态
   - 压缩
 ——雅达雅达

我为上面的每个类类型创建了Editor Template 。

我想要一个Business带有提交表单的通用编辑器模板,该表单将整个结构发布到单个操作并保存它,既适用于现有实体,也适用于新实体。

  1. Editor Template是正确的方法吗?我如何沿着整个下线提交表格?
  2. 如何使添加删除按钮在表单中添加/删除电话号码?
  3. 我如何订购集合中的项目(即我希望每个电话号码附近都有箭头,以便用户可以在客户端列表中向上或向下移动它,然后处理服务器上的保存,因为我已经有了解决方案)。

最重要的是,我的问题是如何将正确的值发布回服务器,以及如何修改客户端上的内部集合。一旦正确的数据以这种或另一种方式在服务器上,我就会知道如何处理它。我的问题是客户端和数据提交的正确方式。

更新

我看到了这个答案,它基本上回答了我问题的第一部分,但后两个仍然存在(添加-删除-订单按钮-在客户端管理集合)。
我的问题不是如何在客户端的 DOM 中添加/删除/重新排序行,而是如何修改客户端数据,然后在服务器中接收它,如下所示:

[HttpPost]
public ActionResult Save(Business business)
{
  /// blah blah
}

更新

以下是我尝试插入新数据的方法:

看法:

@Ajax.ActionLink("Add", "AddCustomField", new AjaxOptions { UpdateTargetId = "customFields", InsertionMode = InsertionMode.InsertAfter })

行动:

public PartialViewResult AddOpeningTimes()
{
  var ot = new OpeningTimes();
  ot.WorkingPeriods.Add(new WorkingPeriod());
  var e = EditorFor(ot);
  //just here for debugging, the values are both empty strings
  e.ViewData.TemplateInfo.HtmlFieldPrefix = ViewData.TemplateInfo.HtmlFieldPrefix;
  return e;
}
//this method is on the base controller:
protected PartialViewResult EditorFor<TModel>(TModel model)
{
  return PartialView("EditorTemplates/" + typeof(TModel).Name, model);
}

问题是name适当的字段没有根据需要枚举(Branches[0].CustomField[0].Key),相反,它只是Key.

4

1 回答 1

1

据我所知,没有“简单”的方法可以做到这一点。

添加按钮- 您必须连接创建表单一部分的 javascript(例如电话类型选择和电话文本框)并设置其 ID/名称。基本上,您会找到表单中的最后一项,其名称为 Phone[ x].PhoneType,然后将表单新部分的值设置为适当的值x + 1

避免自己生成表单部分的一个选项是创建一个隐藏的“模板”并复制它。然后更改 id 和 name。

删除按钮- 如果您只是从 DOM 中删除项目,您会在序列中创建间隙,而 MVC 不知道如何处理。一种可能的方法是使用隐藏字段将表单中的项目标记为已删除,然后在服务器上进行处理。

重新排序——我会在任何需要这个功能的地方添加一个名为 Order 的属性,然后在重新排序时将其呈现为隐藏并使用 javascript 进行更改。添加项目时,您还必须适当地设置它。

在这些情况下有用的属性还有:IsNew、IsUpdated - 与 IsDeleted 一起允许在服务器上进行相对简单的处理。

当然,如果您有嵌套集合,每个集合都需要添加/删除/重新排序功能,那么执行和调试会有些困难。

更新

渲染局部视图的动作无法知道 html 前缀应该是什么,因为它没有上下文(父级是 Branch 对象等)。

如果您想使用 AJAX,我建议将 html 字段前缀作为参数 ( public PartialViewResult AddOpeningTimes(string htmlPrefix)) 发送。htmlPrefix 可以是Branches[0].CustomField[last_custom_field + 1].. 这可能是实现您想要的最干净的方法,即使它实际上不是很干净。

于 2013-05-07T18:51:29.820 回答