xmlplus组件设计系列的数据网格(10)
在本章中,我们要实现一个网格组件,它不仅提供最基本的数据显示功能,还提供排序和数据过滤功能。
数据源
为了测试我们即将编写的网格组件,我们使用了以下数据源。该数据源包含两部分,即表头数据集和表体数据集。网格组件实例的最终列数由标题数据集的长度决定。
var data={ gridcolumns :[' name ',' power'],grindata :[{ name: ' Chuck Norris ',power: Infinity },{ name: '李小龙',power: 9000 },{ name : '成龙',power: 7000 },{ name: ' Jet Li ',power : 8000 }]};顶层设计
在视觉上,我们自然地将网格组件分为表头和表体。这个网格组件有三个功能,所以它应该提供三个动态接口。但是,我们注意到排序功能是通过单击标题来执行的,并且标题是网格组件的一部分,因此应该内置该功能。因此,事实上,我们的网格组件只公开了两个动态接口:一个用于过滤,另一个用于接收数据源。所以我们可以得到一个顶层设计如下。
datagrid : { XML : ` table id=' table ' Thad id=' Thad '/Tbody id=' Tbody '/table `,fun:函数(sys,items,opts){ function setValue(data){ items . Thead . val(data . grid columns);items . t body . val(data . GridColumns,data . GridAta);}函数筛选器(filterKey) {//filter function}返回{val:setvalue,filter 3360 filter };}}设计标题
表头只有一行,所以可以直接给它提供tr元素。tr元素的子项目th的数量取决于标题数据集的长度,因此需要动态创建。因为这个元素包含排序函数,所以需要单独封装。以下是我们页眉的设计。
the d : { XML : ` the ad id=' the ad ' tr id=' tr '/the ad `, fun :函数(sys,items,opts){ fun setValue(value){ sys . tr . children()。调用(' remove ');data . foreach(item=sys . tr . append(' Th ')。值()。val(项目));}返回{ val : SetValue };}}表头数据项组件提供文本设置界面。组件本身不负责排序,它只完成自己视图状态的改变和排序命令的分派。排序命令的分发需要携带两个数据:一个是排序关键字,即标题文本;另一个排序方向,向上或向下。
th : { CSS : ' # active { color : # fff;} # active # arrow { opa city 3360 1;} # active # key { color: # fff} \ # arrow { display : inline-block;垂直对齐:中间;宽度: 0;高度: 0;左边距left: 5pxopacity: 0.66}\ #asc { border-left: 4px实心透明;border-right: 4px实心透明;border-bottom: 4px实心# fff}\ #dsc { border-left: 4px纯色透明;border-right: 4px实心透明;border-top: 4px实心# fff} ',XML : ' th id=' th ' \ span id=' key '/span id=' arrow '/\/th ',fun:函数(sys,items,opts){ var order=' # ASC ';this.watch('sort ',function (e,key,order) { sys.key.text()。toLowerCase()==key | | sys . th . remove class(' # active ');});this.on('click ',function(e){ sys . th . addCLaSS(' # active ');sys . arrow . remove class(order);order=order=='#asc '?# dsc ' : ' # ascsys.arrow.addClass(订单)。notify('sort ',[sys.key.text()。toLowerCase(),order]);});sys . arrow . addCLaSS(' # ASC ');返回{ val : sys . key . text };}}设计表体
表体可以有多行,但表体只负责显示数据,所以实现起来比表头简单很多。
tbody : { XML : ` t body id=' t body '/`,fun:函数(sys,items,opts){ function setValue(GridColumns,GridAta){ sys . t body . children()。调用(' remove ');grid ATA . foreach(data=tr=sys . t body . append(' tr ');grid columns . foreach(key=tr . append(' TD ')。文本(数据[键]);));}返回{ val : SetValue };}}添加排序功能
为了便于管理,我们把排序功能单独封装成一个组件,该组件提供一个排序接口,同时侦听一个排序消息。一旦接收到排序消息,则记录下关键字与排序方向,并派发一个表体刷新命令。
排序: { fun:函数(sys,items,opts) { var sortKey,sortOrderthis.watch('sort ',function (e,Key,order) { sortKey=key,sortOrder=orderthis。触发器(‘更新’);});返回函数(数据){返回sortKey?data.slice().排序(函数(a,b) { a=a[sortKey],b=b[sort key];返回(a===b?0 : a b?1 : -1) * (sortOrder=='#asc '?1 : -1);}) :数据;};}}要完整地实现排序功能,对组件数据网格作一些修正,主要是内置上述的排序功能组件并侦听表体刷新指令。一旦接收到刷新指令,则对表体数据完成排序并刷新表体。
datagrid : { XML : ' table id=' table '萨德id='萨德'/t body id=' t body '/Sort id=' Sort '/table `,fun:函数(sys,items,opts){ var data={ grid columns :[],grid data :[]};函数setVaLue(value){ data=value;物品。thead。val(数据。grid columns);物品。t型车身。val(数据。GridColumns,数据。GridAta);}函数过滤器(filterKey) { //过滤函数} this.on('update ',function(){ items。tbody。val(项目。排序(数据。GridAta));});返回{ val: setValue,filter : filter };}}加入过滤功能
与排序功能的加入流程类似,我们把过滤功能单独封装成一个组件,该组件提供一个过滤接口,同时侦听一个过滤消息。一旦接收到消息,则记录下过滤关键字,并派发一个表体刷新命令。
滤波器: { fun:函数(sys,items,opts){ var filter key=' ';this.watch('filter ',function (e,key){ filter key=key。tolowercase();这个。触发器(‘更新’);});返回函数(数据){返回数据。过滤器(函数(行){返回对象。键(行)}。有些(函数(键){返回字符串(行[键])。toLowerCase().indexOf(筛选器密钥)-1;});});};}}另外需要对组件数据网格作一些修正,修正内容与上述的排序功能的加入类似,区别在于额外完善了过滤器接口以及对消息作用域进行了限制。下面是我们最终的网格组件。
datagrid : { CSS : ` # table { border : 2px solid # 42b 983;边界半径: 3px背景-color : # fff;} # table th {底色: # 42b 983color: rgba(255,255,255,0.66);光标:指针;-网络工具包-用户-选择:无;蚊子用户-选择:无;-ms-用户-选择:无;用户选择:无;} #表格TD {底色: # F9 F9} #table th,# table TD { min-width : 120 px;padding: 10px 20px } `,XML : ' table id=' table '萨德id='萨德'/t body id=' t body '/Sort id=' Sort '/Filter id=' Filter '/table `,map: { msgscope: true },fun:函数(sys,items,opts){ var data={ grid columns :[],grid data :[]};函数setVaLue(value){ data=value;物品。thead。val(数据。grid columns);物品。t型车身。val(数据。GridColumns,数据。GridAta);}函数筛选器(过滤键){ sys。桌子。notify(' filter ',filter键);} this.on('update ',function(){ items。tbody。val(项目。过滤器(项目。排序(数据。gridata)));});返回{ val: setValue,filter : filter };}}值得注意的是这里一定要在映射项中配置限制消息作用域的选项。否则,当在一个应用中实例化多个网格组件时,消息就会互相干扰。
测试
最后我们来测试下我们完成的组件,测试的功能主要就是刚开始提到的三个:数据展示、排序以及过滤。
索引: { CSS : ' # index { font-family : Helvetica纽伊,Arial,无衬线字体;font-size : 14pxcolor: # 444} \ #搜索{边距: 8px 0;} ',xml: 'div id='index'\ Search输入id=' Search '/\ Table id=' Table '/\/div ',fun:函数(系统、项目、选项){项目。桌子。val(数据);sys.search.on('input ',e=items。桌子。过滤器(系统。搜索。prop(' value '));}}本系列文章基于xmlplus框架。如果你对xmlplus没有多少了解,可以访问www.xmlplus.cn。这里有详尽的入门文档可供参考。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
版权声明:xmlplus组件设计系列的数据网格(10)是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。