[ASP NET MVC] 表单 Partial View / Editor Template 使用抉择
表单 Partial View / Editor Template 使用抉择 前言
最近有不少同事都会问到“为什么在这边要使用Editor Tamplate? 怎么不用Partial View来做?”,其实如果想要知道各自适用的时机,首先就必须了解两者差异为何。从以下表格不难发现,两者都是从VIEW中将ViewModel之Boo属性对象传入Partial View / Editor Template,并且都是使用@Html.EditorFor() 方法来产出Html 元素,但最终产出Html Input元素名称prefix却不相同。因此以下将针对各自特性来思考适用情境。
适用情境
使用Partial View或Editor Tempalte除共用考量因素外,就是避免页面过于庞大造成维护不易,因此在拆解复杂数据输入页面区块时,我们需要考量表单数据被送出的方式,是否所有数据都隶属于同一个表单中,亦或者会有分散在各表单的情况,需要有各自被送出的需求。以下提供两种使用情境供读者参考。
Editor Template
单一表单情况下,我们若想将各子属性类拆解成独自的检视,让复杂表单不会这么庞大时,就可以使用Editor Template来实现。简略示意图如下,在Editor Template中若是透过@Html.EditorFor()产出Html元素时,元素名称会以传入对象属性名称(VMA/VMB)作为 prefix,因此在按下Submit送出表单数据到后端时,便可依照名称将数据完整地Binding至ViewModel中。
Partial View
在多表单情况下,可考虑依照各表单Model来拆解成各自Partial View使用。简略示意图如下,在Partial View中若是透过@Html.EditorFor()产出Html元素时,元素名称并不会以传入对象属性名称(VMA/VMB)作为 prefix,因此可利用此特性,让各表单送出属于自己的Model数据至Controller中。
实践演练
假设目前有个新增使用者功能需要实践,由于画面可能会很复杂(身家调查之类),因此可能会存在许多不同种类的资讯,所以希望将表单页面稍微分割一下,把表单中连络资讯(Contact)及教育资讯(Education)给分割出来,预期界面如下所示。虽然知道此时应使用EditorTemplate来实做会比较合适,但抱持着实验的精神,我们就姑且先使用Partial View来实做,看看会发生什么问题。
首先定义检视Model(UserCreateViewModel)、连络资讯(Contact)及教育资讯(Education)相关类。
public class UserCreateViewModel { public string UserName { get; set; } public Contact Contact { get; set; } public Education Education { get; set; } } public class Contact { public string Phone { get; set; } public string Email { get; set; } } public class Education { public string HightSchool { get; set; } public string University { get; set; } }
接着设计输入连络资讯(Contact)及教育资讯(Education)的Partial View页面
为了让结果更加清晰,直接透过@Html.NameFor()把输入框元素名称印出,方便后续比较使用。
_ContactPartialView.cshtml @model PartialViewWebApp.ViewModel.Contact @{Layout = null;}
_EducationPartialView.cshtml @model PartialViewWebApp.ViewModel.Education @{Layout = null;}
主页面(View)如下,使用Partial View来呈现连络资讯(Contact)及教育资讯(Education)输入界面。
@model PartialViewWebApp.ViewModel.UserCreateViewModel @{ ViewBag.Title = "Create"; } @using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.ValidationSummary(true,new { @class = "text-danger" })
产生画面如下,我们可以看到元素名称并没有依照对象属性阶层来命名,因此将数据POST到后端时,除了UserName可以正确绑定至UserCreateViewModel外,其他透过Partial View产出输入框中的数据并无法正确Binding至UserCreateViewModel。
最终会造成部分数据的遗失
接着使用EditorTemplate来实做。首先建立EditorTemplates数据夹,并且在刚目录中建立Contact.cshtml及Education.cshtml来对应Contact及Education类,而各类对应的EditorTemplate内容其实与先前设计的Partial View完全相同,因此不再此赘述了。
然后调整一下主页面,改使用EditorTemplate来呈现连络资讯(Contact)及教育资讯(Education)
@model PartialViewWebApp.ViewModel.UserCreateViewModel @{ ViewBag.Title = "Create"; } @using (Html.BeginForm()) { @Html.AntiForgeryToken() @Html.ValidationSummary(true,new { @class = "text-danger" }) name: @Html.NameFor(model => model.UserName)
产生的画面如下,我们可以看到元素名称依照对象属性阶层来命名,因此将数据POST到后端时,所有数据都可以依据名称,正确Binding至userCreateViewModel中。
结果如预期般正确Binding至userCreateViewModel中。
结论
Partial View 与 Editor Template 虽然都可以传入对象来呈现独立的检视,但是若是牵涉到表单或需要POST数据到后端时,需要特别注意两者差别。Partial View 在使用 @Html.EditorFor() 产生Html元素时,就如同一般View的情况只根据检视中定义的Model来命名Html元素名称;而使用EditorTemplate时,会依照传入对象的属性名称作为产出Html元素名称之prefix,让元素名称可对应至主Model类结构。
参考资讯
http://stackoverflow.com/questions/13746697/mvc3-4-multiple-forms-using-partial-views http://stackoverflow.com/questions/10608766/post-a-form-with-multiple-partial-views 希望此篇文章可以帮助到需要的人 若内容有误或有其他建议请不吝留言给笔者喔 ! 原文:大专栏 ?[ASP NET MVC] 表单 Partial View / Editor Template 使用抉择 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc-3 – 如何在mvc3的dropdownlist中获取国家/地区
- ASP.NET MVC正则表达式路由约束
- 编辑资源文件而不重新编译ASP.NET应用程序
- asp.net-mvc – 在[授权]失败后显示404错误页面
- ASP.NET MVC Ajax错误返回视图而不是ajax
- asp.net – 如何在页面加载中以编程方式向页面添加控件?
- asp.net-mvc – Azure git部署 – 第二个程序集中缺少引用
- asp.net – GridView’GridView1’触发的事件PageIndexChan
- asp.net – 将文本框和按钮放在mvc razor app中
- linq – 将表达式树从一种类型转换为另一种具有复杂映射的类
- asp.net-mvc – ASP.NET MVC HandleError不工作(
- asp.net – 如何使用app_GlobalResource或app_Lo
- ASP.NET Core WebAPI 实现CRUD
- asp.net – 使用HttpRequestMessage.Properties传
- asp.net – 为什么Web架构松散耦合?
- 在Azure中为ASP.NET Core Web应用程序设置SQL连接
- asp.net – 如何添加验证到我的POCO(模板)类
- asp.net页面如何知道哪个按钮触发了回发?
- asp.net-mvc – 如何在没有IoC容器的情况下对您的
- asp.net-mvc – 在asp.net mvc中的视图中设置页面