【ExtJs】与后台数据库交互的带分页表格组件grid的查询
ExtJs的表格组件Grid是可以分页的,并且这个组件是随时随地地与后台数据库进行这交互。正如VC的MFC中的List表格控件一样。
基本上,这个表格控件作为OA系统的主角,配合《【ExtJs】利用树状结构、Border布局与标签页刻划OA界面》(点击打开链接)就真的是一个完整的OA系统了。
然而网上对于此组件的叙述非常糟糕,各类杂七杂八的资料,层出不同的后端语言,让人根本看不明白。下面举一个例子来说明Grid组件怎么查询数据库的数据,并且分页现实出来。
一、基本目标
比如Mysql数据库有一张用户信息表,如下图所示:
然后,我要把它放到Grid.html并且每页2个结果地显示出来,如下图:
二、基本思想
这个项目的目录结构如下图:
必要的Ext资源不在上面的目录结构中。其中Grid.html就是前台显示页面,formSubmit.php解释Grid.html中传递过来的分页信息,到model.php把Mysql数据库中的user表查询出来,再用Ajax打回到Grid.html显示。
formSubmit.php关键是打印出诸如以下的Json字符串,Grid.html直接在等待接受如下的信息,如果接受不到,会一直处于读取的状态:
{ 'success':true, 'total':3, 'data':[ {'id':1,'username':'a','password':'b'}, {'id':2,'username':'c','password':'b'}, {'id':3,'username':'s','password':'b'} ] }
其中total是data中一共有多少项,data是每一项的数据。
三、制作过程
1、Grid.html
首先在HTML仅仅是引入ExtJs的资源:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>ExtGrid</title> <script type="text/javascript" src="../js/ext-all.js"></script> <script type="text/javascript" src="../js/bootstrap.js"></script> <script type="text/javascript" src="../js/ext-lang-zh_CN.js"></script> <link href="../ext-theme-classic/ext-theme-classic-all.css" rel="stylesheet" type="text/css"> </head> <body> </body> </html>之后,先构造一个User实体、对象、模型、Object什么的,反正就是那个意思!ExtJs是这样要求的,我也不像写这么复杂!
Ext.define('user',{ extend:'Ext.data.Model', fields:[ {name:'id',type:'int'}, {name:'username',type:'string'}, {name:'password',type:'string'} ] });这个对象中的fields中的Json数组,基本上与数据库中的表格对应,也与下面Grid表格控件所要显示的列对应。
其次,定义一个所谓的ExtJs数据中心store。制定这个数据中心的模型是user,还有各项属性与各类杂七杂八的固定配置。
var userStore=Ext.create('Ext.data.Store',{ model:'user', pageSize:2,//每页显示数目 proxy:{ type:'ajax', url:'formSubmit.php',//提供Json字符串的页面 reader:{ type:'json', root:'data', totalProperty:'total'//总项数 } }, autoLoad:true });最后还是那个Grid表格控件,这个ExtJs的表格控件相当复杂的,要数据中心提供数据支持才能正常运行。
Ext.create('Ext.grid.Panel',{ title:'用户信息表', renderTo: Ext.getBody(), store:userStore,//此表格控件的数据由userStore数据中心提供支持 columns:[ {text:'ID',dataIndex:'id',flex:1}, {text:'用户名',dataIndex:'username',flex:1}, {text:'密码',dataIndex:'password',flex:1} ], bbar:{ xtype:'pagingtoolbar',//底部工具栏是分页工具栏 store:userStore,//按照userStore的数据进行分页 displayInfo:true//显示共XX页,每页显示XX条的信息 } });此控件的列定义中,text为呈现给用户的列头,dataIndex是指明此列到底与数据中心中的model的哪一项对应。比如我在user实体中定义了username这列,那么这里“用户名”的数据就是username这列的数据,且为string类型。flex:1代表自动列宽。
2、formSubmit.php
这页,如果用户在Grid.html定义每一页显示2个,那么无论它翻到哪一页,你都会收到limit=2这个变量,如果用户翻到第1页,那么你会收到start=0这个变量,如果第2页,则start=1,换句话说,你会收到两个变量,你的任务就是利用这两个变量,构造出诸如如下的Json字符串,直接在这页打印出来!
{ 'success':true, 'total':3,//数据库一共有多少项,这个值应该是固定的。 'data':[ {'id':1,'username':'a','password':'b'}, {'id':2,'username':'c','password':'b'} ]//在本页中,你要grid.html显示的东西 }
因此便有了如下的语句。其中$total的值,$data字符串的构造,直接利用model.php中的方法求出。搞完一大轮,把结果打印。打印$data的时候,如果这个json项,不是最后一项,则添上逗号,搞json数组,最后一项千万不要有逗号,否则会出现《【JavaScript】数组定义末尾请不要留下逗号》(点击打开链接)的问题。
<?php $start=$_REQUEST["start"]; $limit=$_REQUEST["limit"]; include_once("model.php"); $db=new db(); $user=$db->getUserInfoByPaging($start,$limit); $total=$db->getUserTotalNum(); $data=""; for($i=0;$i<count($user);$i++){ $data.="{'id':".$user[$i]['id'].",'username':'".$user[$i]['username']."','password':'".$user[$i]['password']."'}"; if(($i+1)!=count($user)){ $data.=","; } } echo "{ 'success':true, 'total':{$total}, 'data':[{$data}] }"; ?>
Jsp的用户我建议你直接用Servlet或者SSH直接在一个Java中打印这些东西到页面了。用诸如如下的语句即可,其中SSH则还需要用HttpServletResponse response=ServletActionContext.getResponse();取出Respond对象。
PrintStream out = new PrintStream(response.getOutputStream()); response.setContentType("text/html;charSet=utf-8"); out.print("打印内容");Aspx可以利用respond.write来搞。
3、model.php
这个真的没什么好说的,直接在《【php】利用原生态的JavaScript Ajax为php进行MVC分层设计,兼容IE6》(点击打开链接)已经说过了。都是一些很简单的php操作数据库代码而已。反正数据库的查询结果通通用一个二维数组保存起来。就是SSH中的XXList的移植版。
分页的查询,查询通过把数据库的所有结果查询出来,再进行分页,把分页的结果再放到另一个数组里面再打回formSubmit.php,这样必定能够准确分页。不要根据什么id查询第X个项。如果这张表的id是断层,某个用户通过在操作数据库之类的问题,将有可能出现不准确的分页。
同时,按正常来说,这里面只是操作一张表的,因此这个类命名成db没有所谓,按正常来说,应该命名成user。这样就真的严格按照那些什么垃圾框架、团队开发标准了。
<?php function createCon(){ //数据库的地址是localhost:3306,数据库用户名(第二项)是root,数据库密码(第三项)是root $con=mysql_connect("localhost","root","root"); if(!$con){ die("连接失败!"); } //要操作test数据库 mysql_select_db("test",$con); //防止乱码 mysql_query("set names utf8;"); return $con; } class db{ public function getUserTotalNum(){ $con=createCon(); $result=mysql_query("select * from user;"); $userList=array(); for($i=0;$row=mysql_fetch_array($result);$i++){ $userList[$i]['id']=$row['id']; $userList[$i]['username']=$row['username']; $userList[$i]['password']=$row['password']; } mysql_close($con); return count($userList); } public function getUserInfoByPaging($start,$limit){ $con=createCon(); $result=mysql_query("select * from user;"); $userList=array(); for($i=0;$row=mysql_fetch_array($result);$i++){ $userList[$i]['id']=$row['id']; $userList[$i]['username']=$row['username']; $userList[$i]['password']=$row['password']; } $user=array(); for($i=0,$j=$start;$j<($start+$limit);$i++,$j++){ if(empty($userList[$j])){ break; } $user[$i]=$userList[$j]; } mysql_close($con); return $user; } } ?>
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。