ecToDo Framework实现ajax支持的原理
时间:2006-12-19 来源:一地风飞
由于多方原因,ecToDo Framework自发布预览版后,一直未有更进一步的开发,最近,有朋友问到ecToDo Framework是否支持AJAX,于是有了如下想法:
注:下面代码并不即时可用,只阐明实现原理
/**
* Ajax实现,放在libs 以Factory::loadLibs('ajax')调用
*/
class Ajax {
private $script = '';
private $json = array();
/**
* 注册响应动作,$action为动作,多个用","分隔;
*/
function register($action,$method ="get"){
if($method == "post") $handle = "ajax.post();";
else $handle = "ajax.get();";
$actions = explode(",",$action);
$request = Request::getInstance();
for($i = 0,$nums = count($actions) ; $i$nums ; $i++){
$this -> script .= "\nfunction {$actions[$i]}(param){var ajax = new Ajax(\"?c={$request->get('c')}&act={$actions[$i]}\",param);{$handle}}";
}
}
/**
* 输出jsCode,javascript的httpRequest对象
*/
function getJs(){
$ajCode =
function Ajax(sUrl,sQueryString) {
this.Url = sUrl;
this.sQueryString = sQueryString;
this.XmlHttp = this.createXMLHttpRequest();
if (this.XmlHttp == null) { alert("Error:Can't create XMLHttpRequest object");return;}
var objxml = this.XmlHttp;
objxml.onreadystatechange = function (){Ajax.handleStateChange(objxml)};
}
Ajax.prototype.createXMLHttpRequest = function() {
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
try { return new XMLHttpRequest(); } catch(e) {}
return null;
}
Ajax.prototype.get = function () {
var sUrl = this.Url+"&timeStamp=" + new Date().getTime() + "&" + this.sQueryString;
this.XmlHttp.open("GET",sUrl,true);
this.XmlHttp.send(null);
}
Ajax.prototype.post = function() {
var sUrl = this.Url + "&timeStamp=" + new Date().getTime();
this.XmlHttp.open("POST",sUrl,true);
this.XmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
this.XmlHttp.send(this.sQueryString);
}
Ajax.handleStateChange = function (XmlHttp) { //当成功接收到响应结果时,用parse函数解析处理结果
if (XmlHttp.readyState == 4) {if (XmlHttp.status == 200) {parse(XmlHttp.responseText);} else {alert("Error:Can't open the service's Url");}}
}
function parse(re){ //操作处理,对应不同的代码调用不同的方法
var re = eval(re);
for(var i=0;i{
if(re[0] == 0) setAttr(re[1],re[2],re[3]); //改属性
if(re[0] == 1) {//用隐藏的方法实现移除对象
setAttr(re[1],'disable','true');
setAttr(re[1],'style.display','none');
}
if(re[0] == 4) alert(re[1]);
}
}
function setAttr(id,attr,v){ //设置属性的方法
var ob = document.getElementById(id);
var arrAtt = attr.split(".");
for(var i=0;i{ob = ob[arrAtt];}
ob[arrAtt] = v;
}
EOD;
return "{$ajCode}{$this->script}\n"; //返回全部javascript代码,直接用于前台模板页面
}
//设定对象属性值
function setData($objId,$attribute,$data){
$this -> json[] = "[0,'$objId','$attribute','$data']";
}
//移除对象
function remove($objId){
$this -> json[] = "[1,'$objId']";
}
//新建对象
function create($objId,$type,$value='',$pid = ''){
$this -> json[] = "[2,'$objId','$type','$value','$pid']";
}
//加入事件(id,事件,操作),i.e. b1,onclick,alert('ok');
function addEvent($id,$event,$op){
$this -> json[] = "[3,'$objId','$event','$op']";
}
function addAlert($msg){
$this -> json[] = "[4,'$msg']";
}
//返回自身(编码后的响应代码)
function __toString(){
return "[".implode(",",$this->json)."]";
}
}
?>
应用步骤:
1.controller
class testAjax extends Controller{
function index(){
$response = Response::getInstance();
$ajax = Factory::loadLibs('Ajax');
$ajax -> register('a1','post'); //声明处理方法
$response -> set('ajaxJs',$ajax -> getJs()); //替换前台脚本变量
return new ViewSmarty('ajaxtest.html');
}
function a1(){
$ajax = Factory::loadLibs('Ajax');
$ajax -> setData('d2','style.display','none'); //将d2的style.display设为none
$ajax -> remove('d3'); //移除d3
$ajax -> setData('d1','innerHTML','测试'); //将d1的innerHTML设为 测试
$ajax -> setData('d1','value','button'); //设置d1的值
echo $ajax;
}
}
2.前面html(smarty实现)
{%$response->get('ajaxJs')%}
adfasdf
被隐藏
这被移走
##################################################
原理描述:
虽然,我未对ecToDO Framework进行过系统的修改,但也会偶尔把自己的新想法实现在里面,所以,之前提供下载的版本是"过时的",并不能兼容以上代码,我会在适当时候放出最新的版本,这里所说明的只是ajax的实现原理..
1.首先看控制器中的index方法,它初始化了ajax对象,并注册声明了a1方法,使用post提交,这会生成需要的javascript代码(xmlHttpRequest对象,声明方法的实现,返回结果的解析处理等),使用getJs方法放到前台html代码中..
2.在HTML中为指定的控件事件添加a1方法,当该方法被触发时,会自动进行ajax方式的命令提交(向控制器的a1方法提交请求)
3.a1的控制方法实现:调用ajax对象的setData,remove等方法(具体实现方法还需再认真考虑,更好地实现更多的处理),并使用ajax的__toString魔术函数以json的数组方式返回响应结果,前台接收到结果后,再解析处理,使用Dom方式更新页面,至此,一次ajax方式的交互完成..
简单地说,一次交互过程是:前台触发命令,后台按不同的命令执行不同的操作,并按约定格式返回响应数据,前台再根椐返回结果解析、处理、更新!
注:下面代码并不即时可用,只阐明实现原理
/**
* Ajax实现,放在libs 以Factory::loadLibs('ajax')调用
*/
class Ajax {
private $script = '';
private $json = array();
/**
* 注册响应动作,$action为动作,多个用","分隔;
*/
function register($action,$method ="get"){
if($method == "post") $handle = "ajax.post();";
else $handle = "ajax.get();";
$actions = explode(",",$action);
$request = Request::getInstance();
for($i = 0,$nums = count($actions) ; $i$nums ; $i++){
$this -> script .= "\nfunction {$actions[$i]}(param){var ajax = new Ajax(\"?c={$request->get('c')}&act={$actions[$i]}\",param);{$handle}}";
}
}
/**
* 输出jsCode,javascript的httpRequest对象
*/
function getJs(){
$ajCode =
function Ajax(sUrl,sQueryString) {
this.Url = sUrl;
this.sQueryString = sQueryString;
this.XmlHttp = this.createXMLHttpRequest();
if (this.XmlHttp == null) { alert("Error:Can't create XMLHttpRequest object");return;}
var objxml = this.XmlHttp;
objxml.onreadystatechange = function (){Ajax.handleStateChange(objxml)};
}
Ajax.prototype.createXMLHttpRequest = function() {
try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) {}
try { return new ActiveXObject("Microsoft.XMLHTTP"); } catch(e) {}
try { return new XMLHttpRequest(); } catch(e) {}
return null;
}
Ajax.prototype.get = function () {
var sUrl = this.Url+"&timeStamp=" + new Date().getTime() + "&" + this.sQueryString;
this.XmlHttp.open("GET",sUrl,true);
this.XmlHttp.send(null);
}
Ajax.prototype.post = function() {
var sUrl = this.Url + "&timeStamp=" + new Date().getTime();
this.XmlHttp.open("POST",sUrl,true);
this.XmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
this.XmlHttp.send(this.sQueryString);
}
Ajax.handleStateChange = function (XmlHttp) { //当成功接收到响应结果时,用parse函数解析处理结果
if (XmlHttp.readyState == 4) {if (XmlHttp.status == 200) {parse(XmlHttp.responseText);} else {alert("Error:Can't open the service's Url");}}
}
function parse(re){ //操作处理,对应不同的代码调用不同的方法
var re = eval(re);
for(var i=0;i{
if(re[0] == 0) setAttr(re[1],re[2],re[3]); //改属性
if(re[0] == 1) {//用隐藏的方法实现移除对象
setAttr(re[1],'disable','true');
setAttr(re[1],'style.display','none');
}
if(re[0] == 4) alert(re[1]);
}
}
function setAttr(id,attr,v){ //设置属性的方法
var ob = document.getElementById(id);
var arrAtt = attr.split(".");
for(var i=0;i{ob = ob[arrAtt];}
ob[arrAtt] = v;
}
EOD;
return "{$ajCode}{$this->script}\n"; //返回全部javascript代码,直接用于前台模板页面
}
//设定对象属性值
function setData($objId,$attribute,$data){
$this -> json[] = "[0,'$objId','$attribute','$data']";
}
//移除对象
function remove($objId){
$this -> json[] = "[1,'$objId']";
}
//新建对象
function create($objId,$type,$value='',$pid = ''){
$this -> json[] = "[2,'$objId','$type','$value','$pid']";
}
//加入事件(id,事件,操作),i.e. b1,onclick,alert('ok');
function addEvent($id,$event,$op){
$this -> json[] = "[3,'$objId','$event','$op']";
}
function addAlert($msg){
$this -> json[] = "[4,'$msg']";
}
//返回自身(编码后的响应代码)
function __toString(){
return "[".implode(",",$this->json)."]";
}
}
?>
应用步骤:
1.controller
class testAjax extends Controller{
function index(){
$response = Response::getInstance();
$ajax = Factory::loadLibs('Ajax');
$ajax -> register('a1','post'); //声明处理方法
$response -> set('ajaxJs',$ajax -> getJs()); //替换前台脚本变量
return new ViewSmarty('ajaxtest.html');
}
function a1(){
$ajax = Factory::loadLibs('Ajax');
$ajax -> setData('d2','style.display','none'); //将d2的style.display设为none
$ajax -> remove('d3'); //移除d3
$ajax -> setData('d1','innerHTML','测试'); //将d1的innerHTML设为 测试
$ajax -> setData('d1','value','button'); //设置d1的值
echo $ajax;
}
}
2.前面html(smarty实现)
{%$response->get('ajaxJs')%}
adfasdf
被隐藏
这被移走
##################################################
原理描述:
虽然,我未对ecToDO Framework进行过系统的修改,但也会偶尔把自己的新想法实现在里面,所以,之前提供下载的版本是"过时的",并不能兼容以上代码,我会在适当时候放出最新的版本,这里所说明的只是ajax的实现原理..
1.首先看控制器中的index方法,它初始化了ajax对象,并注册声明了a1方法,使用post提交,这会生成需要的javascript代码(xmlHttpRequest对象,声明方法的实现,返回结果的解析处理等),使用getJs方法放到前台html代码中..
2.在HTML中为指定的控件事件添加a1方法,当该方法被触发时,会自动进行ajax方式的命令提交(向控制器的a1方法提交请求)
3.a1的控制方法实现:调用ajax对象的setData,remove等方法(具体实现方法还需再认真考虑,更好地实现更多的处理),并使用ajax的__toString魔术函数以json的数组方式返回响应结果,前台接收到结果后,再解析处理,使用Dom方式更新页面,至此,一次ajax方式的交互完成..
简单地说,一次交互过程是:前台触发命令,后台按不同的命令执行不同的操作,并按约定格式返回响应数据,前台再根椐返回结果解析、处理、更新!
相关阅读 更多 +
排行榜 更多 +