
用ExtJs+Linq+Wcf打造簡(jiǎn)單grid
上篇文章ExtJs與WCF交互:生成樹(shù)中闡述了用wcf產(chǎn)生json數(shù)據(jù)給extjs產(chǎn)生樹(shù)控件的用法,本文將著重講述如何用wcf+extjs+linq打造一個(gè)支持排序和列刷選的grid
上篇文章ExtJs與WCF交互:生成樹(shù)中闡述了用wcf產(chǎn)生json數(shù)據(jù)給extjs產(chǎn)生樹(shù)控件的用法,本文將著重講述如何用wcf+extjs+linq打造一個(gè)支持排序和列刷選的grid。閑話(huà)少敘 ,下面是操作步驟和實(shí)現(xiàn)效果圖
第一步:在vs2008中創(chuàng)建一個(gè)支持.net framework 3.5的網(wǎng)站,此處之所以強(qiáng)調(diào)支持.net framework 3.5是為了使用linq
第二步:將運(yùn)行時(shí)需要的Extjs的資源文件拷貝到項(xiàng)目目錄,具體可見(jiàn)示例項(xiàng)目
第三步:假設(shè)在本機(jī)sql2005中存在數(shù)據(jù)庫(kù)sharelist,里面有一個(gè)數(shù)據(jù)表stocks,效果如下:
數(shù)據(jù)庫(kù)文件sharelist.mdf在示例項(xiàng)目db文件夾中。如果需要測(cè)試,可以將其附加到自己的sql2005數(shù)據(jù)庫(kù)服務(wù)器中。
在網(wǎng)站項(xiàng)目中創(chuàng)建一個(gè)Linq To Sql類(lèi):DataClasses.dbml,方法如下如所示:
點(diǎn)擊添加之后,出現(xiàn)下面的Linq To Sql向?qū)?
在本文只使用左面面板,在服務(wù)器資源管理器中添加對(duì)數(shù)據(jù)庫(kù)sharelist的連接,效果如下:
點(diǎn)擊數(shù)據(jù)表stocks,然后拖動(dòng)stocks數(shù)據(jù)表到左面面板,拖動(dòng)后效果如下:
點(diǎn)擊stocks,然后更改類(lèi)名稱(chēng)為Stock:
更改后效果為:
好,到此我們基本完成了linq to sql類(lèi)的設(shè)計(jì),我們?cè)诮鉀Q方案管理器中打開(kāi)生成的類(lèi)代碼文件中,其中包括類(lèi):Stock ,為了使其能夠被WCF使用
,對(duì)類(lèi)添加DataContractAttribute,對(duì)屬性添加DataMemberAttribute,添加好之后的代碼為:

linq to sql類(lèi)生成的代碼并添加了wcf支持
#pragma warning disable 1591

//------------------------------------------------------------------------------

// <auto-generated>

// 此代碼由工具生成。

// 運(yùn)行庫(kù)版本:2.0.50727.1433

//

// 對(duì)此文件的更改可能會(huì)導(dǎo)致不正確的行為,并且如果

// 重新生成代碼,這些更改將會(huì)丟失。

// </auto-generated>

//------------------------------------------------------------------------------

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Data.Linq;

using System.Data.Linq.Mapping;

using System.Linq;

using System.Linq.Expressions;

using System.Reflection;

[System.Data.Linq.Mapping.DatabaseAttribute(Name="sharelist")]

public partial class DataClassesDataContext : System.Data.Linq.DataContext



{


private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();



Extensibility Method DefinitionsExtensibility Method Definitions#region Extensibility Method Definitions

partial void OnCreated();

#endregion


public DataClassesDataContext() :

base(global::System.Configuration.ConfigurationManager.ConnectionStrings["sharelistConnectionString"].ConnectionString, mappingSource)


{

OnCreated();

}


public DataClassesDataContext(string connection) :

base(connection, mappingSource)


{

OnCreated();

}


public DataClassesDataContext(System.Data.IDbConnection connection) :

base(connection, mappingSource)


{

OnCreated();

}


public DataClassesDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :

base(connection, mappingSource)


{

OnCreated();

}


public DataClassesDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :

base(connection, mappingSource)


{

OnCreated();

}


public System.Data.Linq.Table<Stock> Stock


{

get


{

return this.GetTable<Stock>();

}

}

}


[Table(Name="dbo.stocks")]
[DataContract]
public partial class Stock



{


private string _company;


private double _price;


private double _change;


private double _changepercent;


private System.DateTime _lastupdated;


public Stock()


{

}


[Column(Storage="_company", DbType="NVarChar(50) NOT NULL", CanBeNull=false)]
[DataMember]
public string company


{

get


{

return this._company;

}

set


{

if ((this._company != value))


{

this._company = value;

}

}

}


[Column(Storage="_price", DbType="Float NOT NULL")]
[DataMember]
public double price


{

get


{

return this._price;

}

set


{

if ((this._price != value))


{

this._price = value;

}

}

}


[Column(Storage="_change", DbType="Float NOT NULL")]
[DataMember]
public double change


{

get


{

return this._change;

}

set


{

if ((this._change != value))


{

this._change = value;

}

}

}


[Column(Storage="_changepercent", DbType="Float NOT NULL")]
[DataMember]
public double changepercent


{

get


{

return this._changepercent;

}

set


{

if ((this._changepercent != value))


{

this._changepercent = value;

}

}

}


[Column(Storage="_lastupdated", DbType="DateTime NOT NULL")]
[DataMember]
public System.DateTime lastupdated


{

get


{

return this._lastupdated;

}

set


{

if ((this._lastupdated != value))


{

this._lastupdated = value;

}

}

}

}

#pragma warning restore 1591


第四步:在網(wǎng)站項(xiàng)目中創(chuàng)建一個(gè)啟用了Ajax的WCF服務(wù):ArrayGridService.svc,然后將其中的類(lèi)代碼更改為:

using System;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Activation;

using System.ServiceModel.Web;

using System.Collections.Generic;



[ServiceContract(Namespace = "")]

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]

public class ArrayGridService



{

// 添加 [WebGet] 屬性以使用 HTTP GET

[OperationContract]

[WebInvoke(ResponseFormat = WebMessageFormat.Json, Method = "GET", UriTemplate = "GetStocks")]

public Stock[] GetStocks()


{

DataClassesDataContext dbContext = new DataClassesDataContext();

IQueryable<Stock> res = dbContext.Stock.Select(stock => stock);

return res.ToArray<Stock>();

}

// 在此處添加更多操作并使用 [OperationContract] 標(biāo)記它們

}
在頁(yè)面文件中,在<%@ ServiceHost中添加Factory="System.ServiceModel.Activation.WebServiceHostFactory",然后在web.config中將<enableWebScript/>替換成為<webHttp/>,注意這兩個(gè)操作是必須的。到此wcf服務(wù)也準(zhǔn)備齊備。
第五步:創(chuàng)建一個(gè)BasicGrid.aspx,然后在頁(yè)面中添加extjs必要的鏈接和腳本支持,并添加頁(yè)面元素,完成后的代碼為:

BasicGrid.aspx頁(yè)面文件

<%
@ Page Language="C#" AutoEventWireup="true" CodeFile="BasicGrid.aspx.cs" Inherits="BasicGrid" %>


<!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 runat="server">

<title>extjs+wcf+linq 打造grid</title>

<link rel="stylesheet" type="text/css" href="resources/css/ext-all.css" />


<script type="text/javascript" src="adapter/ext/ext-base.js" charset="gb2312"></script>


<script type="text/javascript" src="ext-all.js" charset="gb2312"></script>


<script type="text/javascript" src="array-grid.js" charset="gb2312"></script>


<link rel="stylesheet" type="text/css" href="grid-examples.css" />

<link rel="stylesheet" type="text/css" href="shared/examples.css" />


<script type="text/javascript" src="shared/examples.js" charset="gb2312"></script>

</head>

<body>

<form id="form1" runat="server">

<div>

<h1>

extjs+wcf+linq 打造grid</h1>

<div id="grid-example">

</div>

</div>

</form>

</body>

</html>


頁(yè)面中有對(duì)<script type="text/javascript" src="array-grid.js" charset="gb2312"></script>,其中的array-grid.js便是產(chǎn)生grid所需要的腳本,它訪問(wèn)上一步中開(kāi)發(fā)好的wcf服務(wù),將服務(wù)方法GetStocks返回的json數(shù)據(jù)與extjs的grid進(jìn)行綁定,具體代碼如下:

ExtJs與Wcf交互生成grid的腳本代碼

/**//**//**//*

* Ext JS Library 2.1

* Copyright(c) 2006-2008, Ext JS, LLC.

* licensing@extjs.com

*

* http://extjs.com/license

*/



Ext.onReady(function()
{


// example of custom renderer function


function change(val)
{


if(val > 0)
{

return '<span style="color:green;">' + val + '</span>';


}else if(val < 0)
{

return '<span style="color:red;">' + val + '</span>';

}

return val;

}


// example of custom renderer function


function pctChange(val)
{


if(val > 0)
{

return '<span style="color:green;">' + val + '%</span>';


}else if(val < 0)
{

return '<span style="color:red;">' + val + '%</span>';

}

return val;

}


var proxy=new Ext.data.HttpProxy(
{url:'ArrayGridService.svc/GetStocks'});


// create the data store


var store = new Ext.data.SimpleStore(
{

fields: [



{name: 'company'},



{name: 'price', type: 'float'},



{name: 'change', type: 'float'},



{name: 'pctChange', type: 'float'},



{name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}

]

});



//定義reader

var reader=new Ext.data.JsonReader(



{

},[



{name: 'company'},



{name: 'price'},



{name: 'change'},



{name: 'pctChange',mapping:'changepercent'},



{name: 'lastChange',mapping:'lastupdated'}

]

)

//構(gòu)建Store


var store=new Ext.data.Store(
{

proxy:proxy,

reader:reader

});

//載入

store.load();



// create the Grid


var grid = new Ext.grid.GridPanel(
{

store: store,

columns: [



{id:'company',header: "公司", width: 160, sortable: true, dataIndex: 'company'},



{header: "單價(jià)", width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price'},



{header: "變動(dòng)", width: 75, sortable: true, renderer: change, dataIndex: 'change'},



{header: "變動(dòng)百分比", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange'},



{header: "最后更新", width: 100, sortable: true, renderer: Ext.util.Format.dateRenderer('Y年m月d日'), dataIndex: 'lastChange'}

],

stripeRows: true,

autoExpandColumn: 'company',

height:350,

width:600,

title:'股市行情',

viewConfig:



{

columnsText:'列',

sortAscText:'升序',

sortDescText:'降序'

}

});


grid.render('grid-example');


grid.getSelectionModel().selectFirstRow();

});


到此,linq部分,wcf部分,extjs部分均開(kāi)發(fā)完成。
第五步:在瀏覽器中瀏覽BasicGrid.aspx,效果圖如下:
說(shuō)明大功告成。
說(shuō)明:這幾篇都是簡(jiǎn)單的實(shí)踐,有關(guān)extjs部分絕大部分參考extjs中的示例,但也做了稍稍的修改,后面的文章會(huì)逐漸深入一些。
示例項(xiàng)目:
/Files/jillzhang/ExtJsWcfLinqGrid.part1.RAR
/Files/jillzhang/ExtJsWcfLinqGrid.part2.RAR