文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>ecToDo Framework实现ajax支持的原理

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方式的交互完成..
简单地说,一次交互过程是:前台触发命令,后台按不同的命令执行不同的操作,并按约定格式返回响应数据,前台再根椐返回结果解析、处理、更新!


相关阅读 更多 +
排行榜 更多 +
幸运硬币官方正版下载

幸运硬币官方正版下载

休闲益智 下载
宝宝来找茬手机版 v9.86.00.00 安卓版

宝宝来找茬手机版 v9.86.00.00 安卓版

休闲益智 下载
翻滚飞机大战最新版 v1.0.4 安卓版

翻滚飞机大战最新版 v1.0.4 安卓版

飞行射击 下载