Fork me on GitHub
[ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面
随着最终用户对用户体验需求的不断提高,实际上我们很多情况下已经在按照桌面应用的标准来设计Web应用,甚至很多Web页面本身就体现为一个单一的页面。对于这种复杂的页面,我们在设计的时候不可以真的将所有涉及的元素通通至于某个单独的View中,将复杂页面相对独立的内容“分而治之”才是设计之道。我们可以借鉴Smart Clent应用的设计方式:将一个Windows Form作为应用的容器(Smart Client Shell),在操作过程中动态地激活相应的用户控件(Smart Part)并加载到容器中。对于一个复杂页面来说,我们也只需要将其设计成一个容器,至于运行过程中动态显示的内容则可以通过Ajax调用获取相应的HTML来填充。[源代码从这里下载] 目录 一、实例演示 二、作为容器的View 三、显示联系人列表 四、弹出“修改联系人”对话框 五、联系人信息的最终修改 一、实例演示 我们先来演示一个简单的例子,假设我们要设计一个“联系人”管理的页面。该页面初始状态如左图所示,它仅仅具有一个用于输入查询条件(First Name和Last Name)进行联系人查询的表单。当用户输入相应的查询条件之后点击“Retrieve”按钮,相应的联系人列表显示以表格的形式显示出来(中图)。当我们点击作为ID的链接后,会以“模态对话框”的形式显示当前联系人的编辑“窗口”(右图)。 这个“单页面应用”是通过ASP.NET MVC开发的,接下来我们来逐步介绍如果将同一页面中的这三块不同的内容提取出来进行“分而治之”。 二、作为容器的View 如下所示的是表示联系人的Contact类型的定义,没有什么特别之处: 1: public class Contact 2: { 3: [Required] 4: public string Id { get; set; } 5: [Required] 6: public string FirstName { get; set; } 7: [Required] 8: public string LastName { get; set; } 9: [Required] 10: [DataType(DataType.EmailAddress)] 11: public string EmailAddress { get; set; } 12: [Required] 13: [DataType(DataType.PhoneNumber)] 14: public string PhoneNo { get; set; } 15: } 联系人管理对应的HomeController定义如下。简单起见,我们通过一个静态字段来表示维护的联系人列表。我们仅仅列出了默认的Action方法Index,它会直接将作为“容器页面”的View呈现出来。 1: public class HomeController : Controller 2: { 3: private static List contacts = new List 4: { 5: new Contact{Id = "001", FirstName = "San", LastName = "Zhang", EmailAddress = "zhangsan@gmail.com", PhoneNo="123"}, 6: new Contact{Id = "002", FirstName = "Si", LastName = "Li", EmailAddress = "zhangsan@gmail.com", PhoneNo="456"} 7: }; 8: 9: public ActionResult Index() 10: { 11: return View(); 12: } 13: //其他Action方法 14: } 如下所示的是Index.cshtml的定义,在这里使用了Twitter的Bootstrap,所示我们引用了相应的CSS和JS。这个主体部分包含三个
,分别对应着上述的三个部分。 1: 2: 3: Contacts 4: 5: 6: 7: 8: 11:
12: 13: 14: 15: 16: 17: 18: 19: 20: 表示“查询表单”的部分定义在如下所示的Partial View(QueryFormPartial.cshtml),直接通过调用HtmlHelper的Partial方法呈现在当前View中。 1: @{ 2: Layout = null; 3: } 4: using (Ajax.BeginForm("Find", new AjaxOptions { OnSuccess = "renderCustomerList" })) 5: { 6:
7: Maintain Contacts 8: 9: 10: 11: 12: 13:
14: } 三、显示联系人列表 QueryFormPartial.cshtml定义了一个以Ajax方式提交的表单,目标Action为具有如下定义的Find,它根据指定的First Name和Last Name筛选匹配的联系人列表,并将其呈现在一个名为ContactListPartial的View中。 1: public class HomeController : Controller 2: { 3: //其他成员 4: public ActionResult Find(string firstName = "", string lastName = "") 5: { 6: var result = from contact in contacts 7: where (string.IsNullOrEmpty(firstName) || contact.FirstName.ToLower().Contains(firstName.ToLower())) 8: &&(string.IsNullOrEmpty(lastName) || contact.LastName.ToLower().Contains(lastName.ToLower())) 9: orderby contact.Id 10: select contact; 11: return View("ContactListPartial",result.ToArray()); 12: } 13: } 如下所示的ContactListPartial.cshtml的定义,这是一个Model类型为IEnumerable的强类型View,它以表格的形式将联系人列表呈现出来。 1: @model IEnumerable 2: @{ 3: Layout = null; 4: } 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: @foreach (var contact in Model) 17: { 18: 19: 20: 21: 22: 23: 24: 25: } 26: 27:
IDFirst NameLast NameEmail AddressPhone No.
@Ajax.ActionLink(contact.Id, "Update", new { contactId = contact.Id }, new AjaxOptions { OnSuccess = "showDialog" , HttpMethod="GET"})@contact.FirstName@contact.LastName@contact.EmailAddress@contact.PhoneNo
从QueryFormPartial.cshtml的定义可以看到,表单成功提交之后会调用一个名为renderCustomerList的JavaScript函数(@using (Ajax.BeginForm("Find", new AjaxOptions { OnSuccess = "renderCustomerList" }))),它以如下的方式定义在Index.cshtml中。从定义了看出,它将获取的数据(实际上ContactListPartial这个View最终的HTML)作为contactList这个
的HTML。 1: 2: 3: 4: 5: 四、弹出“修改联系人”对话框 从ContactListPartial.cshtml的定义可以看到联系人ID以一个链接的方式呈现出来,点击该链接会以Ajax的方式访问Action方法Update,当前联系人ID会作为请求的参数(@Ajax.ActionLink(contact.Id, "Update", new { contactId = contact.Id }, new AjaxOptions { OnSuccess = "showDialog" , HttpMethod="GET"}))。如下所示的是Action方法Update的定义,它根据指定的ID获取对应的联系人,并将其呈现在一个名为ContactPartial 的View中。 1: public class HomeController : Controller 2: { 3: //其他成员 4: [HttpGet] 5: public ActionResult Update(string contactId) 6: { 7: Contact contact = contacts.First(c => c.Id == contactId); 8: return View("ContactPartial", contact); 9: } 10: } 如下所示的ContactPartial.cshtml的定义,这是一个Model类型为Contact的强类型View,它将联系人信息呈现在一个表单中。 1: @model Contact 2: @{ 3: Layout = null; 4: } 5: @using(Ajax.BeginForm("Update", null, new AjaxOptions { HttpMethod = "Post", OnSuccess = "reLoad" }, new { @class = "form-horizontal" })) 6: { 7: 11: 42: 46: } 联系人编译窗口的弹出最终通过调用JavaScript函数showDialog实现(@Ajax.ActionLink(contact.Id, "Update", new { contactId = contact.Id }, new AjaxOptions { OnSuccess = "showDialog" , HttpMethod="GET"})),具体定义如下所示。它将获取到的数据(实际上是ContactPartial这个View最终的HTML)作为第三个
的HTML,并按照Bootstrap的方式以模态对话框的形式将其呈现出来。至于中间的两行代码,在于解决动态添加表单无法实施验证的问题。 1: 2: 3: 4: 5: 五、联系人信息的最终修改 通过ContactPartial.cshtml的定义可以看出编辑联系人表单最终以POST的方式提交到HomeController的Action方法Update(@using(Ajax.BeginForm("Update", null, new AjaxOptions { HttpMethod = "Post", OnSuccess = "reLoad" }, new { @class = "form-horizontal" }))),该Action方法具有如下的定义。它在完成修改之后,返回字符串“OK”表明联系人修改成功。 1: public class HomeController : Controller 2: { 3: //其他成员 4: [HttpPost] 5: public string Update(Contact contact) 6: { 7: contacts.Remove(contacts.First(c=>c.Id == contact.Id)); 8: contacts.Add(contact); 9: return "OK"; 10: } 11: } 联系人修改表单提交后关闭当前窗口并加载新的数据通过具有如下定义JavaScript函数Reload实现(@using(Ajax.BeginForm("Update", null, new AjaxOptions { HttpMethod = "Post", OnSuccess = "reLoad" }, new { @class = "form-horizontal" }))),该函数依然定义在Index.cshtml中。 1: 2: 3: 4: 5: 作者:Artech 出处:http://artech.cnblogs.com/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 分类: [02] 编程技巧10款IT宅男专用Chrome插件推荐  时下了Google Chrome的份额已经超过了IE,尤其是那些IT人士/程序猿/码农,更是推广、使用Chrome的急先锋。下面就是笔者精心挑选的20款实用插件,IT宅男专用,感兴趣的不妨慢慢往下看吧!  1. 鼠标手势 —— Chrome Gestures   * 推荐指数:★★★★★   * 功能概述:鼠标手势、超级拖拽、鼠标平滑滚动、鼠标加速滚动   鼠标手势就不用我多解释了吧,安装这款插件后,Chrome便能在鼠标的“指挥”下完成很多特定操作。除了能够显示出鼠标的轨迹,一个很人性化的设计就是提供了手势功能提示,于是我们便可以在操作时随时掌握即将发生的任务。而且这款插件还有一个特别之处,那就是实现了超级拖拽(即利用拖拽在新标签页中打开链接或文本搜索),进入“扩展程序”→“Chrome Gestures”→“选项”后即可找到这项功能。此外我们也能对默认手势进行修改,甚至为“链接”或“文字”拖拽指定不同的动作(超级拖拽)。IT人士当中Geek是非常多了,熟练使用鼠标手势自然是一个有别于“普通人”的重要特征~  2. 撤销关闭网页—— Sexy Undo Close Tab   * 推荐指数:★★★★★   * 功能概述:还原之前已关闭网页   常在网上走,误关闭网页是常有的事,于是这款能够撤销关闭网页的小插件便应运而生。安装好后会在地址栏右侧生成一个小按钮,点击后便能列出最近关闭的网页,同时这里还提示了每个页面的关闭时间,能够帮助用户更好地辨识。不过它也有一个很大的问题,那就是关闭Chrome后列表将自动清空。这个插件的名字也会让IT宅男们浮想联翩,“Sexy”。。。  3. 一键“爬山”—— 1 Click Web Proxy   * 推荐指数:★★★★★   * 功能概述:一键“爬山”   “爬山”是什么意思?作为IT宅男的你不可能不懂的,哈哈。不多用做介绍了。 这款插件主要特点的是“非常方便”,当网页打不开时,点一下就来了,速度也还算行,能满足普通的“爬山”需求(看网页)。复杂的“爬山”需求就用VPN吧。  4. GMail提醒 —— Google Mail Checker Plus   * 推荐指数:★★★★   * 功能概述:Gmai
posted on 2012-11-25 23:27  HackerVirus  阅读(191)  评论(0编辑  收藏  举报