【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;  
    } 
}  
?> 


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。