这是我的第一个问题,它不是“我该怎么做”,更像是“最干净的方法”,因为我看到了几种方法,但它们似乎都没有吸引我。
这是一个要描述的复杂问题。基本上,我有一个添加/编辑视图,允许用户编辑某些对象的字段。这个对象非常复杂:它有一些字段,它有一个复杂对象的子列表。每个复杂对象大约有40个字段(主要是复选框,单选按钮和日期/时间)。我已将此表示为选择列表:
http://fortheloot.com/public/pictures/sub-items.png
添加按钮会生成包含各种字段的对话框。
问题来了。当用户接受对话框并关闭对话框时,我现在必须将此数据存储在某处,以便用户可以在实际提交表单之前进一步编辑或添加其他子项。
最明显的方法是为每个子对象创建一组隐藏字段。因此,添加子项会为<form>
元素添加40个隐藏元素。添加10个子项目,您有400个隐藏字段。这将正常工作,如果字段名称正确,将绑定到此模型:
public class AddEditModel
{
[Display(Name = "ID")]
public int? Id { get; set; }
[Display(Name = "Name")]
[Required]
[StringLength(100)]
public string Name { get; set; }
public IList<EntryModel> Entries { get; set; }
public class EntryModel { /* fields */ }
}
在模型绑定方面,这似乎看起来很不错,但从客户端来说,我必须跟踪数百个DOM元素,这对我来说似乎很麻烦。从40个其他元素加载和卸载对话框的各种表单元素似乎......就像它可能更好。
理想情况下,我希望能够使用<option>
HTML 5属性或jQuery的data-
函数将数据作为javascript对象存储在data()
元素上,这些是真是一回事。这会使事情的javascript方面更清晰,但它不会自动绑定到回发模型。
如果有办法充分利用两个世界 - 在<option>
元素上存储单个JS对象,或者甚至在单个<input type="hidden" />
元素上存储 - 每个子项目 - 仍然会在回发时正确绑定到模型,我觉得这个问题已经解决了。
答案 0 :(得分:3)
您仍然需要一个html字段(type = hidden)才能将此数据发回服务器。 (你可以使用ajax帖子,但这可能不是一个好主意)
我建议设计一个合理的对象模型来包含这些数据结构,并在每次使用stringify
将其更改为json时序列化对象模型然后当您回发表单时,json将被发送到服务器,您可以使用JavaScriptSerializer将整个对象模型反序列化为一组用c#编写的类(可以模仿javascript中的对象模型)类
编辑:
要反序列化json字符串,可以使用以下代码:
JavaScriptSerializer js = new JavaScriptSerializer();
var c = js.Deserialize<MyClass>(json);
return View(c);
如果你回发json作为帖子消息体(例如$ .ajax或$ .post方法),那么绑定将自动发生在MVC3上,你只需要指定正确的内容类型:application / json in the岗位;请点击我在下面的评论中的链接,了解有关其工作原理的详细信息。
马丁
答案 1 :(得分:3)
您是否考虑过使用像骨干或淘汰赛这样的javascript框架? https://stackoverflow.com/questions/5112899/knockout-js-vs-backbone-js-vs
答案 2 :(得分:1)
由于我们一直在使用javascript,因此我也会坚持使用javascript行为进行回发。当你在列表中输入新项目时,我会继续构建一个多维javascript数组,然后将数组转换为json,然后通过ajax发送到你的MVC路由。
只要json对象符合模型的命名标准,MVC就会在进入action方法之前进行隐式模型绑定。
最简单,最优雅的方法是什么? Knockout.js!在淘汰赛中,您可以创建一个可观察的集合并添加到您的集合中,而不使用javascript数组的grubby语法。然后你会在发出ajax帖子之前调用knockout toJSON方法将集合转换为json。
我强烈建议您在Knockout上观看PluralSight视频,然后下载源代码。
我写了一个样本,但我必须重新开始工作:)