使用JQuery和PHP(Yii框架)不到一年,比较喜欢使用AJAX方式,将JQuery的AJAX机制进行了再次封装,实现功能如下:
1)将处理结果显示到页面的div中,或者任意的元素中(包括input、span)
2)请求可用form.serialize()提交,也可自定义参数
3)带简单的调试信息
编程规范如下:
页面
========
1)需要发送给服务器的元素放到Form中,如使用ajax方式,button放到form以外
2)每个元素需要定义name属性,格式为Class[attribute],Class是数据类别,
一般对应后台数据的Model名称,attribute是属性
3)如使用ajax方式,页面向服务器发送方法为post,数据为form.serialize()
4)使用ajax方式时,服务器返回数据为data,如果返回是一个页面,直接在合适的
div中展示data.html即可;如果返回是一个对象object,则处理data.object.xxx,
xxx为对象的属性。
服务器
=========
1)收到的数据一般放在$_POST['Class']中,具体值保存在$_POST['Class'][attributes]中。
一般Class与Model的数据结构对应
2)处理ajax请求时,首先定义$ret = new AjaxReturn(__FUNCTION__)对象,处理成功后,
设置返回数据$ret->SetData(),成功返回方法为$ret->ajaxReturn(0)。
如果返回一个html格式页面,则SetData($html)即可
如果返回一个对象,页面需要处理对象每个属性,则SetData($object, 'object', 'json),
页面程序处理data.object即可
如果返回提示给用户的错误信息,则SetData(-1, '提示信息')即可,提示信息保持2秒后消失。
在调试模式下,需要一直显示返回信息,则SetData(-2, '信息')即可
3)用try{}catch{}处理页面请求,至少捕获CDBException, CException。
封装的Javascript函数:

1 /** 2 * 处理返回的ajax数据,格式为json编码,内容包括 3 * result.ret: 处理返回码,0为成功,-1为一般错误,-2为未知错误,其他未定义 4 * result.info: 页面提示信息,一般显示在result.div中 5 * result.mode: 处理模式,1为跳转到其他url,0为在本页面继续处理 6 * result.url: 跳转的url链接 7 * result.div: 处理状态显示的层,默认为notice,后台指定 8 * result.data.cmd: 处理本次ajax请求的命令,根据命令调用不同的业务函数 9 * result.data.html: 返回的html格式数据,一般用于特定div的显示,用于UI交互 10 * result.data.page: html显示的页面元素,一般为div或者span的ID,如果希望用户自己处理, 11 * 在后台不设置AjaxReturn->SetData()方法的page属性即可(第2个参数) 12 * 13 * 根据程序需要,可在result后增加其他属性,由特定业务函数继续处理 14 * 15 * 返回值: 16 * object:{命令,{业务逻辑需要的数据}},业务逻辑根据返回值调用对应的业务处理函数 17 * 0: 处理成功,不需要后续处理 18 * 1: 跳转成功 19 * -1: 处理失败 20 * -2: 调试使用 21 * 22 * 依赖: 23 * 页面须包括result.div指定的div,用于显示处理状态 24 */ 25 function handleAjaxResponse(result) 26 { 27 var divid=null; 28 var delay = 3000; // 提示框显示时间,毫秒 29 30 if(result == null) { 31 alert('无返回数据'); 32 return null; 33 } 34 // alert(typeof(result)); 35 // var output = ''; 36 // for (property in result) { 37 // output += property + ': ' + result[property]+'; '; 38 // } 39 // alert(output); 40 if(typeof(result.ret) == "undefined") { 41 alert('返回数据格式错误,没有返回值'); 42 return null; 43 } 44 if(typeof(result.div) == "undefined" || result.div == null) { 45 divid = 'notice'; 46 } 47 else { 48 divid = '#'+result.div; 49 var chk = $(divid).attr('id'); 50 if(typeof(chk) == "undefined") { 51 alert(divid+'未定义,无法显示返回状态信息'); 52 // 允许继续执行 53 } 54 } 55 switch(result.ret) { 56 case 0: // 正确返回 57 if(typeof(result.mode) == "undefined") { 58 alert('返回数据格式错误,没有处理模式'); 59 return null; 60 } 61 if(result.mode == 1) { 62 // 需要跳转 63 $(divid).html(result.info+',正在跳转...').fadeTo(delay,1).fadeOut('fast'); 64 if(typeof(result.url) == "undefined") { 65 alert('返回数据格式错误,未定义调整链接'); 66 return null; 67 } 68 if(result.url != null) { 69 window.location=result.url; 70 } 71 else { 72 alert('未定义跳转链接'); 73 return null; 74 } 75 } 76 else { 77 var info = ''; 78 if(typeof(result.data) == "undefined" || result.data == null) { 79 info = '无返回data数据'; 80 } 81 if(typeof(result.data.cmd) == "undefined" || result.data.cmd == null) { 82 info += 'cmd='+'无返回cmd数据<br>'; 83 } 84 if(typeof(result.data) != "object") { 85 alert('返回数据格式'+typeof(result.data)+'不是对象格式'); 86 return null; 87 } 88 if(typeof(result.info) == "undefined") { 89 result.info = '处理完成'; 90 } 91 $(divid).html(result.info).fadeTo(delay,1).fadeOut('fast'); 92 // 如果定义了返回页面,且html不为空,则显示 93 if(typeof(result.data.html) != "undefined" && result.data.html != null) { 94 if(typeof(result.data.page) != "undefined" && result.data.page != null) { 95 if ( $('#'+result.data.page).length > 0 ) { 96 $('#'+result.data.page).html(result.data.html); 97 } 98 else { 99 alert('页面元素#'+result.data.page+'不存在'); 100 } 101 } 102 } 103 return result.data; // 交给业务函数处理 104 // if(typeof(result.data.cmd) == "undefined") { 105 // alert('返回数据格式错误,没有设置命令'); 106 // return; 107 // } 108 // 某个需要显示的对象处理 109 // if(typeof result.dialog == undefined) { 110 // alert('返回数据错误'); 111 // return; 112 // } 113 // $("#edit-review-object").html(result.dialog); 114 // $("#edit-review-object").dialog({ 115 // width: 500, 116 // height: 500, 117 // modal: true 118 // }); 119 } 120 break; 121 case -1: 122 if(typeof(result.info) == "undefined" || result.info == null) { 123 result.info = '处理错误'; 124 } 125 $(divid).html(result.info).fadeTo(delay,1).fadeOut('fast'); 126 break; 127 case -2: 128 var info = ''; 129 if(typeof(result.data) == "undefined" || result.data == null) { 130 info = '无返回data数据'; 131 } 132 if(typeof(result.data.cmd) == "undefined" || result.data.cmd == null) { 133 info += 'cmd='+'无返回cmd数据<br>'; 134 } 135 else { 136 info += result.data.cmd; 137 } 138 if(typeof(result.data.html) == "undefined" || result.data.html == null) { 139 info += 'html='+'无返回html数据<br>'; 140 } 141 else { 142 info += result.data.html; 143 } 144 if(typeof(result.info) == "undefined" || result.info == null) { 145 info += 'info='+'无返回info数据<br>'; 146 } 147 else { 148 info += result.info; 149 } 150 $(divid).html('非正常返回ret=['+result.ret+']:'+info).show(); 151 break; 152 default: 153 $(divid).html('非正常返回ret=['+result.ret+']:').show(); 154 break; 155 } 156 return null; 157 }
前台页面示例:

后台处理方法示例:

1 public function actionAddposition() { 2 try { 3 $ret = new AjaxReturn(__FUNCTION__); 4 $ret->ajaxReturnDebug($_POST); // 调试代码 5 6 $pos = new PosInfo(); 7 $pos->attributes = $_POST['POS']; 8 $ret->ajaxReturnDebug($pos->attributes); 9 // 设置html返回 10 $ret->SetData($output, 'page_div'); 11 } catch (CDbException $e) { 12 $ret->ajaxReturn(-2, '数据库错误:' . $e); 13 } catch (CException $e) { 14 $ret->ajaxReturn(-2, '内部错误:' . $e); 15 } 16 $ret->ajaxReturn(0); 17 }
AjaxReturn类

1 <?php 2 3 /* 4 * To change this template, choose Tools | Templates 5 * and open the template in the editor. 6 */ 7 8 /** 9 * Description of AjaxReturn 10 * 11 * @author Administrator 12 */ 13 class AjaxReturn { 14 15 const RETURN_DISP = 0; 16 const RETURN_REDIRECT = 1; 17 18 private $data = array(); 19 20 public function __construct($func = null) { 21 $this->data = $this->initData(); 22 $this->setCmd($func); 23 } 24 25 private function initData() { 26 return array( 27 'ret' => 0, // 返回值,0=成功,-1=失败 28 'info' => null, // 返回页面后的提示信息 29 'mode' => 0, // 返回后页面如何处理,0:在原页面继续处理,1:跳转到url 30 'url' => null, // 返回后需要跳转的页面 31 'div' => 'notice', // 页面显示notice的层的ID,默认为"notice" 32 // 返回后根据cmd进行特定业务处理 33 'data' => array( 34 'cmd' => null, // 默认属性cmd,页面根据cmd进行后续业务处理 35 'html' => null, // 返回后需要显示的html数据 36 'page' => null, // 返回的html显示的页面元素 37 //其他属性动态增加到这里 38 ), 39 ); 40 } 41 42 public function SetCmd($func) { 43 if (!empty($func)) { 44 $s = strstr($func, 'action'); 45 if ($s === false) { 46 $s = $func; 47 } else { 48 $s = substr($func, 6); 49 } 50 $this->data['data']['cmd'] = strtolower($s); 51 } else { 52 $this->data['data']['cmd'] = null; 53 } 54 } 55 56 public function SetMode($m) { 57 $this->data['mode'] = $m; 58 } 59 60 public function SetDiv($div) { 61 $this->data['div'] = $div; 62 } 63 64 public function SetRet($ret) { 65 $this->data['ret'] = $ret; 66 } 67 68 public function SetUrl($url) { 69 $this->data['url'] = $url; 70 } 71 72 public function SetInfo($info) { 73 $this->data['info'] = $info; 74 } 75 76 /** 77 * 设置data数组其他属性,用于页面返回后的业务处理 78 * 如果数据格式为json,则按json进行编码,此时$data为array 79 * @param type $attr 80 * @param type $page: html数据在页面显示元素ID,一般是div或者span的ID名, 81 * 为null表示由页面代码处理html数据 82 * @param type $data 83 * @param type $fmt 84 * @return boolean 85 * return true: 成功,false 失败 86 */ 87 public function SetData($data, $page=null, $attr = null, $fmt = null) { 88 if ($attr == null) { 89 $attr = 'html'; 90 } 91 92 if ($fmt != null && $fmt == 'json') { 93 if (is_array($data)) { 94 $this->data['data'][$attr] = $data; 95 } else { 96 return false; 97 } 98 } else { 99 $this->data['data'][$attr] = $data; 100 $this->data['data']['page'] = $page; 101 } 102 103 return json_encode($this->data['data']); 104 return true; 105 } 106 107 public function ajaxReturn($ret = 0, $info = null, $div = null) { 108 $this->SetRet($ret); 109 if ($info == null) { 110 if (empty($this->data['info'])) { 111 $info = '处理完成'; 112 } 113 else { 114 $info = $this->data['info']; 115 } 116 } 117 $this->SetInfo($info); 118 119 if ($div != null) { 120 $this->SetDiv($div); 121 } 122 echo json_encode($this->data); 123 Yii::app()->end(); 124 } 125 126 public function ajaxReturnDebug($obj) { 127 if($obj == null) { 128 $this->ajaxReturn(-2, 'null'); 129 } 130 $t = gettype($obj); 131 $s = null; 132 if($t == "object" || $t == "array") { 133 $s = print_r($obj, true); 134 } 135 else { 136 $s = $obj; 137 } 138 $this->ajaxReturn(-2, $s); 139 } 140 141 public function _debugDumpData() { 142 return json_encode($this->data); 143 } 144 145 } 146 147 ?>