Ext教程 arrow Ext实例分析 arrow EXT+PHP实现基本的CRUD
 
     
EXT+PHP实现基本的CRUD
  2008-06-05
转贴自PHPchina

我们的目标是构建一个用户管理系统,限于时间,只实现CRUD
教程主要分为3部分
1、准备工作
2、Ext可复用布局的编写
3、CRUD的实现
说明:本文主要探讨的是开发的方法,具体的技术部分说明会很少
下面教程开始,回帖后可查看详细[hide]
第一部分 准备工作
    新建网站phpext,下载ext2.0,放在网站根目录lib下面,同时在lib目录下新增user目录,用于存
放自己编写的js
第二部分:Ext可复用布局的编写
    稍微了解Ext一点的都知道,在众多布局中,border布局用来做整体框架是非常不错的。
于是我们的后台框架便采用border布局
  新建文件manage.js,放在 lib/user 文件夹里
//指定空白图片的路径
Ext.BLANK_IMAGE_URL 'lib/ext/resources/images/default/s.gif';
Ext.QuickTips.init();
var 
mainmenuheader;
Ext.onReady(function() {
                        
//顶部
                        
header = new Ext.Panel( {
                                
border true,
                                
region 'north',
                                
height:'100',
                                
html:'<div id=topFrame><p>这里放些你需要的东西</p></div>'
                        
});
                        
//菜单
                        
menu = new MenuPanel();
                        
//主体部分
                        
main = new MainPanel();
                        
//布局开始
                        
var viewport = new Ext.Viewport( {
                                
layout 'border',
                                
items : [headermenumain]
                        });
                        
                });

为了以后项目开发的可复用,我们把menu,main都写成类
  先讲menu,先建个accordion布局的panel容器,用于放置菜单,新建文件lib/user/menu.js

MenuPanel = function() {
        
MenuPanel.superclass.constructor.call(this, {
                
id 'menu',
                
region 'west',
                
title "系统菜单",
                
split true,
                
width 200,
                
minSize 175,
                
maxSize 500,
                
collapsible true,
                
margins '0 0 5 5',
                
cmargins '0 0 0 0',                
                
layout "accordion",
                
layoutConfig : {
                                
titleCollapse true,
                                
animate true
                        
},
                        
items : [ {
                                
title "用户管理",
                                
items : [new UserMenuPanel()]
                        },
                        {
                                
title "基本信息配置",
                                
items : [new OtherMenuPanel()]
                        }]
                });
};
Ext.extend(MenuPanelExt.Panel);

MenuPanel中的UserMenuPanel就是具体的菜单项了
为了省时间,只做了两个,在实际运用中,根据你的实际情况编写
下面说UserMenuPanel

// 用户管理菜单
UserMenuPanel=function()
{        
//调用基类构造函数
        
UserMenuPanel.superclass.constructor.call(this, {
        
autoScroll:true,
        
animate:true,
        
border:false,
        
rootVisible:false,
        
root:new Ext.tree.TreeNode({
        
text'用户管理',
        
draggable:false,
               
expanded:true
            
})        
    }); 
   
this.root.appendChild(new Ext.tree.TreeNode({
                   
text:"用户管理",
                
//这里很重要
                   
listeners:{'click':function(){
                        
//获取组件
                           
var panel=Ext.getCmp("userPanel");
                        
//如果已经创建过,则将其设为active,否则新建并设为active
                           
if(!panel){
                        
//UserPanel是什么,可以先告诉你,这是用户管理的CRUD面板,后面会介绍
                                   
panel=new UserPanel();
                           }
                        
//激活(设为active),openTab方法后面会介绍
                           
main.openTab(panel);
                           }}        
                   }));  
  }
Ext.extend(UserMenuPanelExt.tree.TreePanel);


菜单menu建好了,接下来的就是main部分了,新建lib/user/panel.js,这里是CRUD操作的核心了!
   首先将主panel建好

//主panel
MainPanel = function() {
        
//这就是上面提到的openTab
        
this.openTab = function(panelid) {
                var 
= (typeof panel == "string" panel id || panel.id);
                var 
tab this.getComponent(o);                
                if (
tab) {
                        
this.setActiveTab(tab);
                } else if(
typeof panel!="string"){
                        
panel.id o;
                        var 
this.add(panel);
                        
this.setActiveTab(p);
                }
        };
        
//关闭
        
this.closeTab = function(panelid) {
                var 
= (typeof panel == "string" panel id || panel.id);
                var 
tab this.getComponent(o);
                if (
tab) {
                        
this.remove(tab);
                }
        };
        
MainPanel.superclass.constructor.call(this, {
                
id 'main',
                
region 'center',
                
margins '0 5 5 0',
                
resizeTabs true,
                
minTabWidth 135,
                
tabWidth 135,
                
enableTabScroll true,
                
activeTab 0,
                
items : {
                        
id 'homePage',
                        
title '主页',
                        
closable false,
                        
autoLoad : {
                                
//根据需要,主页面,通常放些介绍信息,使用方法……
                                
url 'about.php'
                        
},
                        
autoScroll true
                
}
        });
};
Ext.extend(MainPanelExt.TabPanel);


Mis.Ext.CrudPanel是CRUD操作的基类,现在我们继承他

//用户管理
UserPanel=Ext.extend(Mis.Ext.CrudPanel,{
        
//id,需唯一
        
id:"userPanel",
        
//标题
        
title:"用户管理",
        
//数据源
        
baseUrl:"user.php",
        
//表单
        
createForm:function(){
        var 
formPanel=new Ext.form.FormPanel({
                
frame:true,
                
labelWidth:70,
                
labelAlign:'right',
                
items:[{
                        
xtype:'fieldset',
                        
title:'基本信息',
                        
autoHeight:true,
                        
items:[{
                                
layout:'column',
                
border:false,
                
defaults:{border:false},
                
items:[{
                            
columnWidth:.5,
                        
layout:'form',
                        
defaultType:'textfield',
                        
defaults:{width:120},
                        
items:[{xtype:"hidden",name:"Id"},
                                                {
fieldLabel:'用户名',name:'Name',width:120}
                                                ]},{
                            
columnWidth:.5,
                        
layout:'form',
                        
defaultType:'textfield',
                        
defaults:{width:104},
                        
items:[{
                                
inputType:'password',
                                
fieldLabel:'密  码',
                                
name:'Password'
                        
}]
                    }]
                        },{
                                
layout:'form',
                    
defaultType:'textfield',
                                
items:[{
                                
width:300,
                                 
name:"Email",
                                 
fieldLabel:'电子邮箱'
                                
}]
                }]
                },{
                        
xtype:'fieldset',
                        
title:'备注信息',
                        
autoHeight:true,
                        
items:[{
                        
xtype:"textarea",
                        
width:380,
                        
height:80,
                         
name:"Remark",
                         
hideLabel:true
                        
}]
                }]
        });        
        return 
formPanel;
    },
        
//创建窗口
    
createWin:function()
    {
            return 
this.initWin(438,300,"用户管理");
    },
    
storeMapping:["Id","Name","Password","Email","Remark"],
    
initComponent : function(){            
    
this.cm=new Ext.grid.ColumnModel([
        {
header"用户名"sortable:true,width300dataIndex:"Name"},
        {
header"密码"sortable:true,width300dataIndex:"Password",renderer:function()
{return 
"******";}},
        {
header"电子邮箱"sortable:true,width300dataIndex:"Email"},
        {
header"备注"sortable:true,width300dataIndex:"Remark"}
        ]);
    
UserPanel.superclass.initComponent.call(this);   //调用基类的方法
    
}
        });



好了,现在布局所涉及到的js基本上搞定了
  现在该是检验效果的时候了,嘿嘿
  新建index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"[url=http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd]http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd[/url]"
>
<
html xmlns="[url=http://www.w3.org/1999/xhtml]http://www.w3.org/1999/xhtml[/url]" >
<
head>
    <
title>实验室管理系统</title>
    <
link href="default.css" rel="stylesheet" type="text/css" />
    <
link rel="shortcut icon" href="favicon.ico" />
    <
link rel="Bookmark" href="favicon.ico" />
    <
link href="lib/ext/resources/css/ext-all.css" rel="stylesheet" type="text/css" />
    <
link href="lib/ext/resources/css/xtheme-slate.css" rel="stylesheet" type="text/css" />
</
head>
<
body>
<!--
加载等待标签-->
<
div id="loadingTab">
    <
div class="loading-indicator">
                <
img src="Images/loading.gif" alt="loading" width="32" height="32" 
style="margin-right:8px;float:left;vertical-align:top;"/>
        <
a href="Default.aspx">xxxx管理系统</a><br />
                <
span id="loading-msg">加载样式表和图片...</span>
  </
div>
</
div>
<
script type="text/javascript">document.getElementById('loading-msg').innerHTML '正在加载
UI组建...'
;</script>
<script language="javascript" type="text/javascript" src="lib/ext/adapter/ext/ext-
base.js"></script>
<script language="javascript" type="text/javascript" src="lib/ext/ext-all.js"></script>
<!--加载ext-lang-zh_CN.js是加在本地化文件,用来显示中文所使用的-->
<script language="javascript" type="text/javascript" src="lib/ext/source/locale/ext-lang-
zh_CN.js"></script>
<script language="javascript" type="text/javascript" src="lib/user/menu.js"></script>
<script language="javascript" type="text/javascript" src="lib/user/panel.js"></script>
<script language="javascript" type="text/javascript" src="lib/user/manage.js"></script>
<script language="javascript" type="text/javascript">document.getElementById('loading-
msg').innerHTML = '正在初始化组建...';</script>
<script language="javascript" type="text/javascript">
                Ext.get('loadingTab').fadeOut({remove: true});//让加载标签消失
</script>
</body>
</html>

第三部分 实现CRUD
1.新建数据库phpext
2.新建表user

CREATE TABLE `user` (
`
IdINT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`
NameVARCHAR50 NOT NULL ,
`
PasswordVARCHAR50 NULL ,
`
EmailVARCHAR150 NULL ,
`
RemarkTEXT NULL 
ENGINE MYISAM ;
INSERT INTO `user` ( `Id` , `Name` , `Password` , `Email` , `Remark` ) 
VALUES (
'1''name1''1234', [email=]' '[/email], 'ss'
), (
'2''name2''name2', [email=]' '[/email], 'ss'
);

3新建Db.php,这里封装数据库操作,简约却不简单:) (其实数据库操作类,不需要功能齐全,关键在于够用)

<?php
/*
*封装一个简单的数据库操作类
*/
class Db
{
var 
$conn;
var 
$error;
//构造函数
function Db($host="localhost",$user="root",$pass="",$db="phpext")
{
  if(!
$this->conn=mysql_connect($host,$user,$pass))
  die(
"can't connect to mysql sever");
  
mysql_select_db($db,$this->conn);
  
mysql_query("SET NAMES 'UTF-8'");
}
//错误信息
function getError()
{
   return 
addslashes($this->error);
}
//直接执行sql,用于更新,删除,添加
function execute($sql)
{
   if(
mysql_query($sql,$this->conn))
   { return 
true;}else{
    
$this->error=mysql_error();
    return 
false;
   }
}
//获取记录数
function findCount($sql)
{
    
$result=mysql_query($sql);
    return 
mysql_num_rows($result);
}
//通过sql语句获取记录集,返回数组
function findBySql($sql)
{
    
$array=array();
    
$result=mysql_query($sql);
    
$i=0;
    while(
$row=mysql_fetch_assoc($result))
       {
      
$array[$i]=$row
   
$i++;
       }
    return 
$array;
}
//$con的几种情况
//空:返回全部记录
//array:eg. array('id'=>'1') 返回id=1的记录
//string :eg. 'id=1' 返回id=1的记录
function toExtJson($table,$start=0,$limit=10,$cons="")
{
   
$sql=$this->generateSql($table,$cons);
   
$totalNum=$this->findCount($sql);
   
$result=$this->findBySql($sql." LIMIT ".$start." ,".$limit);
   
$resultNum count($result);//当前结果数
  
$str="";
  
$str.= "{";
  
$str.= "'totalCount':'$totalNum',";
  
$str.="'rows':";
  
$str.="[";
  for(
$i=0;$i<$resultNum;$i++){
   
$str.="{"
   
$count=count($result[$i]);
   
$j=1;
   foreach(
$result[$i] as $key=>$val)
   {
   if(
$j<$count)
   {
   
$str.="'".$key."':'".$val."',";
   }
   elseif(
$j==$count)
   {
   
$str.="'".$key."':'".$val."'";
   }
   
$j++;
            }
   
   
$str.="}";
   if (
$i != $resultNum-1) {
             
$str.= ",";
         }
  }
  
$str.="]";
  
$str.="}";
  return 
$str;  
}
//通过条件生成sql
function generateSql($table,$cons)
{
    
$sql="";//sql条件
   
$sql="select * from ".$table;
   if(
$cons!="")
   {
   if(
is_array($cons))
   {
     
$k=0;
     foreach(
$cons as $key=>$val)
  {
  if(
$k==0)
  {
  
$sql.="where '";
  
$sql.=$key;
  
$sql.="'='";
  
$sql.=$val."'";
  }else
  {
  
$sql.="and '";
  
$sql.=$key;
  
$sql.="'='";
  
$sql.=$val."'";
  }
  
$k++;
  }
   }else
   {
   
$sql.=" where".$cons;
   }
   }
   return 
$sql;
}
}
?>


4新建user.php
说明,下面的代码仅供参考,因为在实际应用中不可能这么写

<?
require("lib/Db.php");
$db=new Db();
$table='user';
$con="";
$start=isset($_GET['start'])?$_GET['start']:0;
$limit=isset($_GET['limit'])?$_GET['limit']:10;
if(isset(
$_GET['name']))
$con="name like %'".$_GET['name']."'% ";
$sql="";
if(isset(
$_GET['cmd']))
{
   
//获取JSON
   
if($_GET['cmd']=="List")
   {
    echo 
$db->toExtJson($table,$start,$limit,$con);
   }
   
//更新
   
if($_GET['cmd']=="Update")
   {
     
$sql="update user set Name='".$_POST['Name']."',Password='".$_POST['Password']."',Email='".$_POST['Email']."',Remark='".$_POST['Remark']."' where Id='".$_POST['Id']."'";
     if(
$db->execute($sql))
  echo
"{success:true,info:'更新成功'}";
  else
  echo
"{failure:true,info:'更新失败,错误原因为:".$db->getError()."'}";
     
//返回一个json,ext才能正确读取
   
}
   
//新增
   
if($_GET['cmd']=="Save")
   {
     
$sql="insert into user values(null,'".$_POST['Name']."','".$_POST['Password']."','".$_POST['Email']."','".$_POST['Remark']."')";
     if(
$db->execute($sql))
  echo
"{success:true,info:'添加成功'}";
  else
  echo
"{failure:true,info:'添加失败,错误原因为:".$db->getError()."'}";
   }
   
//批量删除
   
if($_GET['cmd']=="Remove")
   {
    
$rows=jsondecode($_GET['json']);
foreach(
$rows as $row)
{
  
$sql="delete from user where Id='".$row."'";
  if(!
$db->execute($sql))
  {
   echo
"删除编号为:".$row."的用户失败";
   break;
  }
}
echo
"删除成功";
   
//为什么这里不返回json?看看js代码,删除的时候用的Ext.data.Connection(),所以返回的数据应该是xmlhttp 一样的,xml,Text任你选择,当然text最简单了
   
}
}
   
//将JSON转为数组
   
function jsondecode($jsonString)
    {
        require_once(
"lib/Ajax.php");
        
$instance =& new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
        return 
$instance->decode($jsonString);
    }
?>
现在php端的CRUD基本上实现了,剩下的事情就是套用方法,把你以前写的网站ect化吧,相信你能成功!
本例代码提供下载
ext.part01.rar (240 KB) ext.part02.rar (240 KB) ext.part03.rar (131.15 KB)
< 上一篇