jQuery是一个重要的客户端框架,ASP.NET MVC默认的项目模板中就带了这个框架。掌握这个框架对于更好地编写ASP.NET MVC应用是非常重要的。事实上,网上有很多文章讲述如何在ASP.NET MVC项目中使用jQuery。例如以下文章就是讲关于jqGrid的:

Using jQuery Grid With ASP.NET MVC

Using jqGrid with ASP.NET MVC

另外,在CodePlex上就有很多项目帮助你更方便地应用jQuery,例如:

jQuery UI Extensions for ASP.NET MVC
jQuery Grid for ASP.NET MVC

但是,要更加方便地使用jQuery,仅仅知道以上还是不够的。

一:了解ASP.NET MVC的局限性

ASP.NET MVC有几处是我不太喜欢的,但是似乎也没有太好的解决方案。

第一件事情是冗余的Action。在一个Controller中每个Action的地位是平等的。但是很遗憾,一个带Form的View总是需要两个Action,一个用来GET;另一个用来POST。而我觉得这两个Action是不平等的。用于Post的Action是依赖用于Get的Action的。我告诉你,这两个Action其实是可以压缩成一个的。另一个完全可以放到System.Web.Mvc中,大家公用,通过传递一个或多个delegate来处理。也就是说,形式上是一个,实际上仍然是两个。说这个问题的意图是想说明,我们可以把一个Ajax服务通过传递一个delegate来实现单入口。

第二件事情是Script的Render。我希望任何TagBuilder都可以引用自己的Script,在Html的Head段最后写入。可惜WebFormViewEngine的Render过程中按次序进行的。这意味着,直到整个页面写入Response你都没有机会去更正对Script的引用。其实我以前写过关于ASP.NET MVC中Script的管理,不过实话说非常丑陋。其实我也可以告诉你,这个是可以实现的。在View中可以定义一个特殊的标签,当遇到这个标签的时候,将已经生成的Html写入缓存,清空HtmlWriter,再Render剩余的部分;最后再Render Script部分,最后交这三者合并,最后写入Response。说这个问题的意图是将客户端复杂化以后给应用带来的困难暴露出来。

任何一件事情,如果单独在服务端完成,这个比较好处理。如果单独在客户端完成,这个也好处理。如果需要客户端和服务端配合,就会弄出一些麻烦来。如果你要在一个页面中显示一个jqGrid,你一共至少需要做四件事情:

1.在你的View中加入相关的引用,包括JavaScript和CSS;包括jQuery、jQuery UI、jqGrid;包括相关的主题。

2.在你的View中适当的地方添加一个table标签,并加上id,用于表格的容器;再添加一个div标签,也加上id,用于分页器的容器。

3.加入相关的脚本,将网格与给定的标签进行绑定。其中需要定义网格的列信息。

4.加入一个数据获取的Action,或者XML格式数据或者JSON格式数据。

对于第1件事情,似乎不算麻烦。如果不是过于挑剔的话甚至没有什么问题。

对于第2件事情和第3件事情,就会有冲突了。可以假设这两件事情是两个人做的,但是他们必须确保他们所使用的id是一样的。一旦不一致,到底算谁的责任?

对于第4件事情,就更麻烦了。因为那已经是服务端的事情了。不仅获取数据的Url要正确,连Column表和数据表也必须一致。一旦不一致,到底算谁的责任?

通常对于要求一致的事情,由一个人做比较好。所以,无比聪明的程序员会通过一个 HtmlHelper来根据单一的定义统一生成。这的确是一个好的思路。所以,使用jQuery是需要进行专门包装的。

二:封装jQuery及其插件

如果要一个基于jQuery的Total Solution,还真有比较大的困难。jQuery本身的功能是相当有限的,其丰富的功能要依赖一大堆的插件。几乎每个插件要用在ASP.NET MVC中都需要包装一下。好在jQuery插件有一些约定,所以封装起来相对比较简单。在封装的时候有一点通常容易被忽略的是:作为独立于应用的封装模块中是可以带自己的Controller的。举个例子来说:如果你封装了一个jQuery UI的主题管理器,主题管理的ModalDialog的Action,包括Get和Post你都是可以包装在一个单独的项目中的。如果你的控制器叫 jQueryController,两个Action分别是ShowThemes和SetTheme,那你可以通过以下代码来实现:

        var currTheme = "";$(document).ready(function() {var doClick = function() {$("#themeGallery td img.currentTheme").removeClass();this.setAttribute("class", "currentTheme");currTheme = this.getAttribute("title");}var doOK = function() {$.post('/jQuery/SetTheme', { theme: currTheme }, function(data) {$("#themeDialog").dialog("close");eval(data);});return false;}var doCancel = function() {$("#themeDialog").dialog("close");}$("#themeDialog").load("/jQuery/ShowThemes");$("#ThemeButton").click(function() {$("#themeGallery td img").click(doClick);var dialogOpts = {modal: true,width: "662px",height: "420px",resizable: false,buttons: { "OK": doOK, "Cancel": doCancel }};$("#themeDialog").dialog(dialogOpts);});});

这样,在任何需要设置主题的地方放一个<a>元素,id定义为ThemeButton即可。基于同样的原理,我们在封装jqGrid的时候,可以使用如下定义的委托:

public delegate GridDataModel QueryableFunc(HttpContextBase context, int page, int rows, string sidx, string sord);

这样,单一的入口就是:

代码

public ActionResult Employees()
{
var model = new GridModel
{
Caption = "Employees",
Loader = (ctx, page, rows, sidx, sord) =>
{
...... 实现数据访问
return new GridDataModel
{
Total = q0.Count(),
Page = page,
Records = q.Count(),
Rows = q.ToArray()
};
}
};
model.Columns.Add(new ColumnModel
{
Name = "Id",
Width = "80px",
Align = ColumnAlign.Right,
Caption = "Id",
Index = "Id",
IsKey = true,
Sortable = true,
Hidden = true
});
...... 加入其他列
return View(model);
}

这样,在View中使用的扩展,生成的JavaScript代码中,Url是由应用无关的模块提供的,以View名称+View中Table的id为标识,存贮在服务端。获取数据时提交该标识,找出数据加载器,从而实现异步数据加载。

jQuery的插件,除了jqGrid是必须封装的以外,jQuery UI也是必须要封装的。虽然很多人包括我在内,对jQuery UI有诸多不满,主要的不满都是基于功能,项目进度严重拖后于Roadmap上的承诺。另外,其代码质量也不如jQuery。不过,毕竟jQuery UI是jQuery官方的产品,受到很多插件依赖,所以,暂时没有可替代的。

此外,还有以下插件需要封装:

  • 带CheckBox的TreeView;
  • 导航Menu和上下文菜单;
  • 封装Google Maps API的gMap;
  • tinyMCE的jQuery插件;
  • 用于布局的Panel插件;
  • 动态Form插件。

三:如何避免拼凑脚本

在ASP.NET MVC中需要经常拼凑脚本,这一点也非常令人讨厌。讨厌的并不是“拼凑脚本”,而是“经常”。需要“经常”拼凑脚本的原因是服务端的内容是动态输出到客户端的。如果通过某种固定的机制,智能地将服务端的单一代码自动生成为客户端内容那将是非常令人高兴的事情。换句话说,你在服务端直接写C#代码,然后有一个专门的工具将这些代码翻译成客户端代码。

我研究过JavaScript#,发现这条路完全行不通。首先,要么翻译源码、要么翻译编译后的代码,但必须是整个文件地翻译,而不能是某个代码段。其次,JavaScript#必须依赖一整套程序集,而这些程序集是特有的。

我建立了一个新的项目,叫jQuery#,基于一套专门的库,然后在运行时以较小的代价来实现反编译,并翻译成JavaScript代码。如果仅仅只是生成jQuery所需要的客户端代码是非常简单的,jQuery API毕竟比较少,每个插件的API也都相当有限。麻烦的是需要插入大量的客户端Event Handler。这才是难点所在。按我的计划,今年6月初会发布jQuery#的第一个版本。 目标是可以这样写View:

代码

<% Html.jQuery(document => {
new jdGrid{
container = "main",
clientId = jQuery.CreateTable("employees"),
pager = jQuery.CreateDiv("empPager"),
data = Model,
open = () => {
jQuery.Element("OpenButton").Disable();
return false;
},
caption = "Employees"
}); %>

ASP.NET MVC + ADO.NET EF 项目实战(三):引入jQuery相关推荐

  1. ASP.NET MVC + ADO.NET EF 项目实战(二):设计过程与设计工具

    工欲善其事,必先利其器.好的工具能够成倍提升工作效率.ASP.NET MVC和ADO.NET EF也是因为其工具出色而受到欢迎.例如: MVC所提供的View模板工具: MVC所提供的View切换.向 ...

  2. ASP.NET Core 技术内幕与项目实战读后感

    前几天拿到了杨中科老师的新书<ASP.NET Core 技术内幕与项目实战>,迫不及待的"两"口气读完了.用一句话来总结,这是一本写给.NET开发者的非常实用的接地气的 ...

  3. 06.简书项目实战三:详情页面和登录功能实现

    简书项目实战三:详情页面和登录功能实现 1. 详情页面布局 这部分的布局比之前的简单多了,就一个标题加上主要内容而已. export default class Detail extends Comp ...

  4. 看一下基于ASP.NET MVC的开源社区项目Orchard

    昨天介绍了基于ASP.NET MVC的框架Catharsis,今天给大家介绍的是基于ASP.NET MVC的一个开源社区项目Orchard,本篇主要介绍一下Orchard是什么,如何下载安装以及安装过 ...

  5. ASP.NET MVC 入门2、项目的目录结构与核心的DLL

    我们新建一个ASP.NET MVC的Web Application后,默认的情况下,项目的目录结构如下: App_Data :这个目录跟我们一般的ASP.NET website是一样的,用于存放数据. ...

  6. YbSoftwareFactory 代码生成插件【九】:基于JQuery、WebApi的ASP.NET MVC插件的代码生成项目主要技术解析...

    YbSoftwareFactory目前已可快速生成ASP.NET  WebForm.MVC.WinForm和WPF的解决方案源代码,所生成的源代码可直接在VS中打开并运行.终端用户还可自行二次开发自己 ...

  7. 学习 ASP.NET MVC (第二回)实战篇

    上篇简单的了解了ASP.NET MVC的基本概念和基本流程,接下来的几篇将通过简单的实例,来看看如何通过ASP.NET MVC创建应用程序.Demo很简单也很基础,高手绕过.   闲话少说,直接进入正 ...

  8. ASP.Net MVC开发基础学习笔记:三、Razor视图引擎、控制器与路由机制学习

    一.天降神器"剃须刀" - Razor视图引擎 1.1 千呼万唤始出来的MVC3.0 在MVC3.0版本的时候,微软终于引入了第二种模板引擎:Razor.在这之前,我们一直在使用W ...

  9. c .net ajax,Asp.net mvc 2中使用Ajax的三种方式

    在Asp.net MVC中,我们能非常方便的使用Ajax.这篇文章将介绍三种Ajax使用的方式,分别为原始的Ajax调用.Jquery.Ajax Helper.分别采用这三种方式结合asp.net m ...

  10. vue项目怎么全局引入jquery

    项目场景: vue项目怎么引入jquery 使用jq的时候报错$ is not defined 在main.js中引入后,组件内使用$报$未定义,只有在组件中import $ from 'jquery ...

最新文章

  1. SAP BADI应用
  2. Eclipse中的checkstyle插件
  3. MVC、MVP和MVVC区别
  4. SpringBoot 文件上传、下载、设置大小
  5. sublime text3支持Vue语法高亮显示步骤(转)
  6. Impala之DDL、DML
  7. C++ 小游戏程序 (共七款)
  8. sd卡无法读取怎么办?内存卡数据恢复,4个好用方法
  9. 完整部署uniswap 合约、前端教程(可部署uniswap到bsc、heco)
  10. 免费滴永恒G,试试无妨
  11. 读书笔记5.4——《让数字说话:审计,就这么简单》:孙含晖
  12. 看天下网络资讯浏览器 下载
  13. 网页轮播图(详细版)
  14. 云栖大会人脸识别闸机【技术亮点篇7】--人脸识别闸机采用
  15. STM32工作笔记007---认识OLED屏和LCD屏的区别
  16. Cshell IF在进行数字计算时 提示 if: Badly formed number.
  17. 个人见解:从瀑布到敏捷——漫画解读软件开发模式变迁史
  18. Eclipse连接天天模拟器进行调试
  19. 中国比较出名的几个皇帝陵墓----秦皇陵
  20. IOS风企业宣传PPT模板

热门文章

  1. CS 231n 学习笔记 03——课程3.1 损失函数
  2. ISL - Ch.2 Statistical Learning
  3. 每日的代码量真的重要么?
  4. QDialog之屏蔽Esc键
  5. /var/lock/subsys作用
  6. 電郵泛濫成災 電話再成新寵
  7. apache2 + django
  8. 加/减/乘/除 下的取余
  9. SoundMorph Dust for Mac(双耳环绕音频颗粒合成仪)
  10. Mac电脑问题:磁盘读写NTFS怎么不行?