ExtJs学习笔记(2)_Basic GridPanel[基本网格]

这一节,将学习如何使用网络上最常见的UI控件_Grid

 

1.静态示例:

静态示例其实官方下载包里,就有sample,这里只贴出代码,后面的如何跟WCF结合,做出动态版的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 ="../resources/css/ext-all.css"   />
     
< script  type ="text/javascript"  src ="../adapter/ext/ext-base.js" ></ script >
    
< script  type ="text/javascript"  src ="../ext-all.js" ></ script >  
    
< title > ExtJs Study </ title >
</ head >
< body >

< script  type ="text/javascript" >
    Ext.onReady(
function() {
    
    Ext.state.Manager.setProvider(
new Ext.state.CookieProvider());//设置缓存

    
//数据来源,实际应用用可动态读取
    var myData = [
        [
'3m Co'71.720.020.03'9/1 12:00am'],
        [
'Alcoa Inc'29.010.421.47'9/1 12:00am'],
        [
'Altria Group Inc'83.810.280.34'9/1 12:00am'],
        [
'American Express Company'52.550.010.02'9/1 12:00am'],
        [
'American International Group, Inc.'64.130.310.49'9/1 12:00am'],
        [
'AT&T Inc.'31.61-0.48-1.54'9/1 12:00am'],
        [
'Boeing Co.'75.430.530.71'9/1 12:00am'],
        [
'Caterpillar Inc.'67.270.921.39'9/1 12:00am'],
        [
'Citigroup, Inc.'49.370.020.04'9/1 12:00am'],
        [
'E.I. du Pont de Nemours and Company'40.480.511.28'9/1 12:00am'],
        [
'Exxon Mobil Corp'68.1-0.43-0.64'9/1 12:00am'],
        [
'General Electric Company'34.14-0.08-0.23'9/2 12:00am'],
        [
'General Motors Corporation'30.271.093.74'9/3 12:00am'],
        [
'Hewlett-Packard Co.'36.53-0.03-0.08'9/1 12:00am'],
        [
'Honeywell Intl Inc'38.770.050.13'9/1 12:00am'],
        [
'Intel Corporation'19.880.311.58'9/1 12:00am'],
        [
'International Business Machines'81.410.440.54'9/1 12:00am'],
        [
'Johnson & Johnson'64.720.060.09'9/1 12:00am'],
        [
'JP Morgan & Chase & Co'45.730.070.15'9/1 12:00am'],
        [
'McDonald\'s Corporation', 36.76, 0.86, 2.40, '9/1 12:00am'],
        ['Merck & Co., Inc.'40.960.411.01'9/1 12:00am'],
        [
'Microsoft Corporation'25.840.140.54'9/1 12:00am'],
        [
'Pfizer Inc'27.960.41.45'9/1 12:00am'],
        [
'The Coca-Cola Company'45.070.260.58'9/1 12:00am'],
        [
'The Home Depot, Inc.'34.640.351.02'9/1 12:00am'],
        [
'The Procter & Gamble Company'61.910.010.02'9/1 12:00am'],
        [
'United Technologies Corporation'63.260.550.88'9/1 12:00am'],
        [
'Verizon Communications'35.570.391.11'9/1 12:00am'],
        [
'Wal-Mart Stores, Inc.'45.450.731.63'9/1 12:00am']
    ];

    
//"变化"字段的格式化输出
    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;
    }



    
//"变化(%)"字段的格式化输出
    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;
    }


    
//创建数据存储(类似c#中的dataset构架)
    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' }
        ]
    }
);
    store.loadData(myData);
//加载数据

    
//创建数据表格
    var grid = new Ext.grid.GridPanel({
        store: store,
        columns: [
            
{ id: 'company', header: "公司名", width: 160, sortable: true, dataIndex: 'company' },
            
{ header: "价格", width: 75, sortable: true, renderer: 'usMoney', dataIndex: 'price' },
            
{ header: "变化", width: 75, sortable: true, renderer: change, dataIndex: 'change' },
            
{ header: "变化(%)", width: 75, sortable: true, renderer: pctChange, dataIndex: 'pctChange' },
            
{ header: "最后更新", width: 85, sortable: true, renderer: Ext.util.Format.dateRenderer('m/d/Y'), dataIndex: 'lastChange' }
        ],
        stripeRows: 
true,
        autoExpandColumn: 
'company',
        height: 
350,
        width: 
600,
        title: 
'简单网络示例'
    }
);

    grid.render(
'grid-example');//宣染指定ID

    grid.getSelectionModel().selectFirstRow();
//默认选择第一行
         
    }
);
</ script >

< button  id ="btnHello" > Hello World </ button >
< div  id ="grid-example" ></ div >
</ body >
</ html >

 

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]的字段

你可能感兴趣的:(gridPanel)