1.静态示例:
静态示例其实官方下载包里,就有sample,这里只贴出代码,后面的如何跟WCF结合,做出动态版的Grid才是本文重点
Ext.onReady(function()
function change(val)
if (val > 0)
} else if (val < 0)
function pctChange(val)
if (val > 0)
} else if (val < 0)
var store = new Ext.data.SimpleStore(
var grid = new Ext.grid.GridPanel(
2.动态示例
先贴出运行效果图
a.先写wcf服务端
(1)新建一个"启用了Ajax的WCF服务",命名为MyService.svc
(2)写一个方法用于取得网格所需的数据
[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class MyService
{
[OperationContract]
[WebInvoke(ResponseFormat = WebMessageFormat.Json, Method = "GET", UriTemplate = "GetClsData")]
public T_Class[] GetClsData()
{
List<T_Class> _Result = new List<T_Class>();
using (DBDataContext db = new DBDataContext())
{
var query = db.T_Classes.Where(c => c.F_Type.ToLower() == "shop").OrderBy(c => c.F_RootID).ThenBy(c => c.F_Orders).Select(c => new { F_ID = c.F_ID,
F_ClassName = c.F_ClassName, F_ParentID = c.F_ParentID,F_Orders = c.F_Orders,F_ReadMe = c.F_ReadMe });
_Result = db.ExecuteQuery<T_Class>(query, true).ToList<T_Class>();
db.Connection.Close();
}
return _Result.ToArray();
}
}
注意:这里是用linq to sql的方法写的,默认情况下linq to sql设计器生成的T_Class类里,是不支持序列化的,ExtJs调用时无法正确序列成JSON字符串,需要手动在类前加上数据契约
[DataContract],在属性前加上[DataMember]
如下:
[Table(Name="dbo.T_Class")]
[DataContract]
public partial class T_Class : INotifyPropertyChanging, INotifyPropertyChanged
{
...
[Column(Storage="_F_ClassName", DbType="NVarChar(256)")]
[DataMember]
public string F_ClassName
{
...
(3)修改svc文件,右击svc文件,选择打开方式-->HTML编辑器,增加Factory="System.ServiceModel.Activation.WebServiceHostFactory"
即
<%@ ServiceHost Language="C#" Debug="true" Service="Ajax_WCF.MyService" CodeBehind="MyService.svc.cs" Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>
(4)修改web.config,找到以下节点(注:Ajax_WCF为项目的命名空间,因各自项目实际情况而异)
<behavior name="Ajax_WCF.MyServiceAspNetAjaxBehavior">
<enableWebScript />
</behavior>
把<enableWebScript />删除,换成<webHttp />
即
<behavior name="Ajax_WCF.MyServiceAspNetAjaxBehavior">
<webHttp />
</behavior>
说明一下:(3),(4)二步是必须的,目的是为了生成Restful WCF,可以在ExtJs里用类似"MyService.svc/GetClsData"这样的url来访问
b.Extjs调用的前端页面
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="02.Grid.aspx.cs" Inherits="Ajax_WCF._02_Grid" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="js/ext2.2/resources/css/ext-all.css" />
<script type="text/javascript" src="js/ext2.2/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="js/ext2.2/ext-all.js"></script>
<title>ExtJs Basic Grid Demo</title>
</head>
<body>
<script type="text/javascript">
Ext.onReady(function() {
var proxy = new Ext.data.HttpProxy({ url: 'MyService.svc/GetClsData' });
var reader = new Ext.data.JsonReader({}, [
{ name: 'F_ID' },
{ name: 'F_ClassName' },
{ name: 'F_Orders' },
{ name: 'F_ParentID' },
{ name: 'F_ReadMe'}]
)
var store = new Ext.data.Store({ proxy: proxy, reader: reader });
store.load();
var grid = new Ext.grid.GridPanel({
store: store,
columns: [
{ id: 'F_ID', header: "分类ID", width: 250, sortable: true, dataIndex: 'F_ID' },
{ header: "分类名称", width: 75, sortable: true, dataIndex: 'F_ClassName' },
{ header: "排序号", width: 75, sortable: true, dataIndex: 'F_Orders' },
{ header: "备注", width: 100, sortable: true, dataIndex: 'F_ReadMe'}],
height: 350,
width: 600,
title: '基本网格示例',
viewConfig: { columnsText: '显示列', sortAscText: '升序', sortDescText: '降序' }
});
grid.render('grid-example');
grid.getSelectionModel().selectFirstRow();
});
</script>
ExtJs_Grid_Demo
<div id="grid-example"></div>
</body>
</html>
ok,完成了。
另外,如果要实现对Grid的查询,可以再加上这几行代码:
JS部分:
var fnAjaxDemo = function() {
var mydata;
Ext.Ajax.request({
url: "MyService.svc/GetClsData?name=" + encodeURIComponent(Ext.get("ProductName").dom.value), //服务器端地址
success: function(request) {
store.loadData(eval(request.responseText));
},
failure: function() {
alert("failure!");
}
});
}
Ext.get("btnRefresh").on("click", fnAjaxDemo);
。。。
html部分:
分类名称:<input type="text" id="ProductName" name="ProductName"/><button id="btnRefresh">查询记录</button>
当然,相应的GetClsData部分也要修改:
[OperationContract]
[WebInvoke(ResponseFormat = WebMessageFormat.Json, Method = "GET", UriTemplate = "GetClsData")]
public T_Class[] GetClsData()
{
string name = CNTVS.TOOLS.Utils.fRequest("name").ToString();
List<T_Class> _Result = new List<T_Class>();
using (DBDataContext db = new DBDataContext())
{
var query = db.T_Classes.Where(c => c.F_Type.ToLower() == "shop");
if (name != "")
{
query = query.Where(p => p.F_ClassName.ToLower().Contains(name.ToLower()));
}
var query2 = query.OrderBy(c => c.F_RootID).ThenBy(c => c.F_Orders).Select(c => new { F_ID = c.F_ID, F_ClassName = c.F_ClassName, F_ParentID = c.F_ParentID, F_Orders = c.F_Orders, F_ReadMe = c.F_ReadMe });
_Result = db.ExecuteQuery<T_Class>(query2, true).ToList<T_Class>();
db.Connection.Close();
}
return _Result.ToArray();
}
最后说明几个注意事项:
1.Ext.onReady(function() {...}这一串script,如果直接写在页面中,必须放在<body>...</body>中,否则网格上右击,设置显示列时,报JS错误,原因不明。
2.WCF的服务端方法,必须设置成JSON格式,另外Method设置为GET,否则运行时,前端页面读不出数据
3.如果设置了autoExpandColumn,则autoExpandColumn对应的列,必须是id对应的列,否则出错
4.服务端的类中,如果有DateTime字符的字段,需要手动修改dbml对应的cs文件,把DateTime改成string,否则序列化时,会产生很怪的值,估计是.Net在序列化成JSON时的bug.
5.为了减少生成的JSON字符串的大小,可以仅在需要输出的类属性上标记[DataMember],这样在生成的JSON字符串,不会包含未标记为[DataMember]的字段