我的模型看起来像这样:
Business - Branch - Phone(*) - Phone Type - Number - Opening hours (*) - Days in week - Working period (*) - From time - To time - Custom field (*) - Name - Value - Address - Address line - City - State - Zip - Yada yada
我为上面的每个班级类型创建了编辑模板。
我希望有一个共同的Business
编辑器模板,其中包含一个提交表单,该表单将整个结构发布到单个操作并保存,无论是现有实体还是新实体。
最重要的是,我的问题是如何将正确的值发布回服务器,以及如何修改客户端上的内部集合。一旦正确的数据以这种方式在服务器上,我将知道如何处理它。我的问题是客户端和正确的数据提交方式。
我看到了this回答,这基本上回答了我问题的第一部分,后两者仍然存在(添加 - 删除 - 订单按钮 - 在客户端管理集合)。
我的问题不是如何在客户端的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
。
答案 0 :(得分:1)
据我所知,没有“简单”的方法可以做到这一点。
添加按钮 - 您必须连接创建表单一部分的javascript(例如,电话类型选择和电话文本框)并设置其ID /名称。基本上,您会找到表单中的最后一项,其名称为Phone [x
]。PhoneType,并使用x + 1
将表单新部分的值设置为适当的值。
避免自己生成表单部分的选项是创建隐藏的“模板”并复制它。然后更改ID和名称。
删除按钮 - 如果您只是从DOM中删除项目,则会在序列中创建间隙,而MVC不知道如何处理。一种可能的方法是使用隐藏字段将表单中的项目标记为已删除,然后在服务器上处理该项目。
重新排序 - 我会将一个名为Order的属性添加到需要此功能的任何内容中,然后将其呈现为隐藏,并在重新排序时使用javascript进行更改。您还必须在添加项目时进行适当设置。
在这些情况下的有用属性还有:IsNew,IsUpdated - 以及IsDeleted允许在服务器上进行相对简单的处理。
当然,如果您有嵌套的集合,每个集合都需要添加/删除/重新排序功能,那么执行和调试将很困难。
<强>更新强>
呈现局部视图的操作无法知道html前缀应该是什么,因为它没有上下文(父级是Branch对象等)。
如果你想使用AJAX,我建议发送html字段前缀作为参数(public PartialViewResult AddOpeningTimes(string htmlPrefix)
)。 htmlPrefix可以是Branches[0].CustomField[last_custom_field + 1].
。它可能是达到你想要的最干净的方式,即使它实际上不是很干净。