1、Extjs教程第五章使用grid显示数据使用grid显示数据毫无疑问,grid是Ext中使用最广泛的组件之一。我们需要以一种易于理解的方式为最终用户展现我们的数据,电子表格就是这种方式之一,而且相当完美应为它做到了,并且让这一观念深入人心。Ext 接受了该观点,并使得它更加灵活而且奇妙。在这一章中我们会: 使用GridPanel来在用户友好的表格中展示结构化的数据; 从服务器或数据库加载数据显示在表格中; 使用表格提供的事件来控制表格的功能和显示; 在表格中采用高级的数据格式化技术; 建立分页表格。我们将说明如何定义表格的行和列,但是更为重要的是,我们将学习如何使表格更为美观。我们可以添加自定
2、义渲染的单元格,并且在其中添加图片,我们还可以根据数据值来改变显示样式。到底什么是表格?Ext的表格和电子表格相似,包含2个重要的部分: 行 列 在这里,我们的列是:Title, Released, Genre, 和 Price。每一行包含像The Big Lebowski, Super Troopers之类的电影。这些行都是我们的数据;表格中的每一行代表数据中的一条记录。在GridPanel中显示结构化的数据:在表格中显示数据需要两个Ext组件: store像数据库一样,追踪要显示的数据; 表格面板提供展现store中数据的方式。在我们开始来实现这些之前,让我们先来看看将被我们使用到的术语,
3、因为这些术语可能会把我们搞糊涂: Columns(列):它引用整个数据列,包含显示数据有关的信息,包括列的head(列标题),在ExtJS中,这些都是Column Model(列模型)的一部分; Fields(字段):它也引用了真个数据列,但是它引用的是实际的数值。在ExtJS里,它被在reader(Ext读取数据的组件)中,用来加载数据。建立data store(数据容器):我们需要做的第一件事就是建立我们的数据,它将会被放到data store之中。data store有不同的类型,可以让我们读取不同形式的数据(XML,JSON等等),并且可以在不同的Ext控件中来完成读取数据的过程。不管
4、数据是JSON,XML还是数组,甚至是我们自己自定义的数据类型,我们都可以通过相同的方式访问,这要感谢data store。下面是一些Ext中默认的data store类型: Simple (Array)(数组) XML JSONA custom data store could be created to read data that does not fit into these categories. 可以创建自定义的data store来读取其他类型的数据。Ext论坛提供了一些用户贡献的data store,例如CSV和ColdFusion形式的数据。在data store中添加数据:
5、初次尝试,我们将建立一个以本地数组为数据源的表格。接下来我们使用到的数据来自一个小的电影数据库,其中包含了一些我最喜爱的电影,这与这章后面用到的来自真实数据库的数据很相似。The data store needs two things: the data itself, and a description of the dataorwhat could be thought of as the fields.data store需要两个东西:数据本身和数据描述如同字段以及其它你能想到的类似的东西。reader(读取器)读取器将被用来读取来自数组的数据,在其中我们会定义数组数据的字段名(fiel
6、d)。读取器相当于一个翻译,它将数据字符串翻译为一行一行的数据来供Ext使用。接下来的代码应该被放到Ext的OnReady函数内部:var store = new Ext.data.Store( data: 1, Office Space, Mike Judge, 1999-02-19, 1, Work Sucks, 19.95, 1 , 3, Super Troopers, Jay Chandrasekhar, 2002-02-15, 1, Altered State Police, 14.95, 1 /.more rows of data removed for readability./
7、 , reader: new Ext.data.ArrayReader(id:id, id, title, director, name: released, type: date, dateFormat: Y-m-d, genre, tagline, price, available );如果我们在浏览器中查看这段代码,我们不会看到任何东西因为data store只是用来加载并跟踪数据的一种方式。现在浏览器的内存中已经有我们的数据了。现在我们只需要决定怎样将它显示给用户。为data store定义数据:reader需要知道从数据存储器中读取哪些字段,所以我们需要定义这些字段。字段使用由对象组
8、成的数组来定义如果数据被挨个读取,那么只需要指定这个字段的名称就可以了。在这个例子中,除了一个字段,其他的都可以通过简单的命名来定义。举个例子,标题字段可以用如下的对象来定义:name: title然而,在我们的用例中,因为我们仅仅把这个字段以一个字符串的形式读取,我们可以简单的定义这个字段的名称以减少一些输入:titlereleased 字段很特殊,是因为我们需要适当处理它的数据,设置它的type为data。对于每种字段格式类型(type),都有一些选项来更明确的定义它的格式。使用日期类型(date type)时,还需要定义dateFormat(时间格式化)属性,它是一个字符串(本例中是Y-
9、m-d)。如果你用过PHP的话,时间格式化字符串看起来很熟悉,因为Ext使用了与PHP相似的时间格式化字符串。name: released, type: date, dateFormat: Y-m-d指定的数据类型:ExtJs有许多途径来适当读取特定数据类型,它们都列在下面:字段类型说明信息string字符串数据int数字使用JS的parseInt函数float浮点型数字使用JS的parseFloat函数booleantrue/falsedate日期数据需要dateFormat配置以下是一些我经常使用的数据类型:字段类型说明用法date包含信息的数据你需要定义dateFormat,它告诉Ext
10、如何把字符串转化为日期。Y-m-d代表了“4字符的年-数字月-数字日”Ext中的dateFormat和PHP 一样,一下连接有对格式化日期的详细说明:int数字数据将数值视为整数int数据常常可以用来做比较,进而完成一些事情,如对两列数据求和。boolean或者boolTrue/False注意布尔值展现的各种形式,你可以把一个字符串强制转化为布尔值,也可以用0、1分别转化为布尔值。如果我们仅仅用刚才的reader显示数据的话,最终会是这样的结果:看上去很丑陋,近乎让人崩溃: released列的type设置为date,也被从字符串转化日期,但是其展现形式却是标准的且丑陋的JS的日期格式幸运的是
11、,Ext可以让它看上去更漂亮; price列被设置为浮点数,但是这里并不需要精确到小数; Avail列被解析成布尔值,即便原始数据不是一个true值。这就是为什么要指定数据类型并且添加一些特殊的选项的原因。显示GridPanel(表格面板):将所有的东西集成到一起的就是GridPanel,它专注于将数据放置到行跟列中,连同列标题,并将所有的东西做简洁的封装。对任何人来说,只是将电影的数据存放于电脑的内存中并不是够,我们需要在表格中展现它:1. 把data store放在GridPanel的代码中:Ext.onReady(function() / add your data store here
12、 var grid = new Ext.grid.GridPanel( renderTo: document.body, frame:true, title: Movie Database, height:200, width:500, store: store, columns: header: Title, dataIndex: title, header: Director, dataIndex: director, header: Released, dataIndex: released, renderer: Ext.util.Format.dateRenderer(m/d/Y),
13、header: Genre, dataIndex: genre, header: Tagline, dataIndex: tagline ););在浏览器中,你看到的将是这样:究竟是怎么做到的呢?我们的data store和一个决定column(列)跟column header(列标题)应该怎样被显示的(column model)列模型加载到了表格中。和先前在reader中定义的字段不同,由于现在已经被定义了,所以reader知道怎么去读数据。配置GridPanel:The GridPanel is the widget that ties everything together: Ext.g
14、rid.GridPanelGridPanel是一个将一切捆绑到一起的控件,我们只需要一些基础的东西来建立它:字段类型说明用法renderTo说明GridPanl显示的位置它的值需要是一个有效的DOM对象,或者DOM元素的id。接下来,我们将会吧GridPanl直接传给其他控件,所以这个配置项将可以不做设置。frame为GridPanel加框为GridPanel添加一个漂亮的边框,这项不是必须的,但是会使得GridPanel在渲染时更加漂亮。height和width定义GridPanel的大小高度是必须被定义的,因为grid不会自己计算表格的高度。但是当我们在布局(layout)中添加grid时
15、,这项就不需要了。store我们的数据对包含数据的data store的引用。columnsColumn model(列模型)定义GridPanel中列的数组。stripeRows设置行条纹当该项为true时,行的颜色将交替变化。grid panel的基本的设置大概象这样:var grid = new Ext.grid.GridPanel(renderTo: Ext.getBody(), frame:true, title: Movie Database, height:200, width:500, store: store, columns: insert columns here );我
16、们几乎可以象读句子一样来读懂这段配置:将我们的grid渲染到页面的body当中,为其加边框,给他一个Movie Database的标题。它的高度为200,宽度为500;它将使用我们的store作为data store,并且有指定的列模型。The one reason why I love object-based configuration so much is that it is human readable. 我喜欢基于对象的配置方法的原因之一就是它的易读性。我们不在用去打开手册查找函数x的第三个参数是什么!只要简单的说“让高为200宽为500”就可以了。定义grid的列模型:为了定义我
17、们的表格列,我们需要先创建一个定义了这些列应该怎么显示、处理的对象数组。columns: header: Title, dataIndex: title, header: Director, dataIndex: director, header: Released, dataIndex: released, header: Genre, dataIndex: genre, header: Tagline, dataIndex: taglinecolumn header(列标题)看上去像这样:列模型中的每个列有很多配置项,但是必须至少定义header和dataIndex。header用来说明列
18、标题(column header)的内容,dataIndex表示列中数据字段的名字我们在建立reader的时候已经定义好了这些。这里还有其它一些列模型的比较有用的配置选项:选项说明用法renderer定义数据的显示形式格式化该列的数据,使其变成我们需要的形式。所有类型的数据都可以被转化,我们将在接下来的几章里做进一步学习。hidden隐藏该列布尔值,决定是否显示该列width定义列的宽度,单位像素定义列的宽度,默认100像素,超出的部分被隐藏起来。sortable决定该是否对该列进行排序布尔值,决定该列是否能够被排序。使用cell renderer(单元格渲染器):我们可以使用单元格渲染来干一
19、些漂亮活。对于如何使得单元格变漂亮以及让它包含更多我们想要的东西来说,几乎没有任何阻碍。我们需要做的,只是定义好ExtJS为我们提供的单元格内置格式化函数。如usMoney,或者建立我们自己的cell renderer(单元格渲染器)。让我们先看下如何使用内置的cell renderer,接下来再建立自己的cell renderer。利用内置的cell renderer格式化数据:很多内置的格式化函数是用来满足通常的渲染需求的。其中我常常用到的是date renderer:renderer: Ext.util.Format.dateRenderer(m/d/Y) 还有一些renderer包含了
20、一些常用的格式化功能,如货币(这里指的是格式化为货币符号),大写,小写。 这里给出一些人们经常要用到的renderer: Renderer说明用途dateRenderer格式化用来显示的日期格式化该列日期为你喜欢的形式,所有形式的日期都可以被转化。uppercaselowercase大写和小写转化转化字符串为完全大写或者小写。Capitalize美化文本格式化文本,让它的大小写都正确。建立可查询的data store自定义单元格渲染:我们将重点聚焦到genre一列上,它里面的值都是数值,我们现在的需求是,能够通过查询在“表单”一章中的data store来找到genre数字对应的文本信息。首先
21、,我们需要往column model中添加一个renderer配置,告诉表格在单元格渲染的时候使用哪个函数:header: Genre, dataIndex: genre, renderer: genre_name现在,我们来写这个函数。这个函数传递了单元格中的值作为第一个参数。第二个参数是单元格对象本身,第三个参数是该表格的data store这两个我们都不需要,所以让我们先不去管它们。function genre_name(val) /genres就是之前第三章中的那个simpleStore return genres.queryBy(function(rec) if (rec.data.
22、id = val) return true; else return false; /如果匹配,则返回相应的文本内容 ).itemAt(0).data.genre;renderer函数传递了单元格当前的数值。这个数值可以被检验并且可以被修改任何return回来的数值都会被渲染在单元格上。queryBy的作用是从store中过滤数据,它接收一个函数来比较每一行的数据,当return为true时,它就使用匹配的行。为了方便考量,我们现在提供这个函数的另一个版本,它和上面的函数功效相同,但是不如第一个易读:function genre_name(val) return genres.queryBy(
23、function(rec) return rec.data.id = val; ).itemAt(0).data.genre;合并两列数据:上面介绍的能够查询data store的renderder很有用。但是,更为经常使用的一个功能是,我们会合并两列为一个单元格,例如,相加两列数值,求平均,求差值,或者合并两列字符串。以电影标题(tilte)列举例,我们可以把tagline和它合并,这样我们就不需要tagline这一列了。首先,我们需要在column model中把tagline这一列的hidden属性设置为true,即隐藏该列。header: Tagline, dataIndex: tag
24、line, hidden: true接下来配置renderer函数,让它来完成合并列的工作:function title_tagline(val, x, store) return +val+store.data.tagline;在这个函数里,我们title加粗,用以区分title和tagline(其实作者还在中间加了换行呢,哈哈)。你可以看到,HTML标签在这里同样好用。最后,不要忘了把这个函数加到column model里啊:header: Title, dataIndex: title, renderer: title_tagline现在的title列如下所示:生成HTML和图片:让我们
25、为每行添加图片来显示每个电影的封面(cover),我们之前发现可以在cell中使用HTML语言,那么现在我们可以通过添加标签,并且在src中指定图片路径来完成这一功能。function cover_image(val) return ; 别忘了设置column的renderer: header: Cover, dataIndex: coverthumb, renderer: cover_image现在的grid看起来是这样的:内置特性:Ext有很多好的内置特性,用来完成更好的电子表格界面。每一列都有一个内置的菜单,提供排序,显示/隐藏列的功能。客户端排序:除非指定grid为服务器端排序,否则E
26、xt是可以在客户端对列进行排序。服务器端排序用在分页数据,或者数据格式不能被客户端排序的时候。客户端排序快捷、简单而且是内置的:header: Tagline, dataIndex: tagline, sortable: true我们也可以在grid渲染完毕后再实现排序功能;var colmodel = grid.getColumnModel();colmodel.getColumnById(tagline).sortable = true;我们的列模型(column model)控制着列和列标题的显示。如果我们能从grid中获得column model的引用,那么我们就可以在渲染后改变列。我
27、们通过使用getColumnById函数来获得某列,只需传递该列的ID到此函数。隐藏/显示列:利用列标题(column header)中的菜单,我们可以让某列显示或者隐藏。在配置里我们也可以对这一属性做设置,让列默认为隐藏的,如下所示:header: Tagline, dataIndex: tagline, hidden: true我们经常在表格渲染完毕后执行列的隐藏,我们可以使用Ext提供的函数来实现这一令人兴奋的功能:Var colmodel = grid.getColumnModel();colmodel.setHidden(colmodel.getIndexById(tagline),
28、true);获取column model的引用可以让我们对列的显示加以改变。列(column)的渲染:我们可以通过拖拽列标题(column header)来实现列之间的重新排序。这都是Ext表格的内置功能。所有的列都可以被任意的拖拽。以上显示的过程是吧price拖到title和director列之间。我们可以通过把GridPanel中的enableColumnMove属性设置为false来屏蔽列拖拽的功能。enableColumnMove: false列移动的事件和grid中的其它事件都可以被监测到并产生相应的响应。据个例子,我们可以监测列的移动然后弹出信息,告诉用户把列拖到了什么位置:gri
29、d.getColumnModel().on(columnmoved, function(cm,oindex,nindex) var title = You Moved +cm.getColumnHeader(nindex); if (oindex nindex) var dirmsg = (oindex-nindex)+ Column(s) to the Left; else var dirmsg = (nindex-oindex)+ Column(s) to the Right; Ext.Msg.alert(title,dirmsg); );很多其他的事件都可以用同样的方式监听到。grid、data store、column model都有它们自己可以被监听到的事件,我们将在这章里学到更具体的内容。在grid里显示服务器端的数据:利用Ext,我们可以把数据以各种方式添加到页面中。我们先前为表格添加本地数组数据。现在我们将要把数据从附加的文件和服务器中取回。从XML文件中加载电影数
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1