Chinaunix首页 | 论坛 | 博客
  • 博客访问: 607056
  • 博文数量: 129
  • 博客积分: 8026
  • 博客等级: 中将
  • 技术积分: 1300
  • 用 户 组: 普通用户
  • 注册时间: 2006-02-21 14:39
文章分类

全部博文(129)

文章存档

2011年(1)

2007年(26)

2006年(102)

我的朋友

分类:

2006-12-19 10:24:52

由于多方原因,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
[i][0] == 0) setAttr(re[i][1],re[i][2],re[i][3]
); //改属性
        if(re
[i][0] == 1) {//用隐藏的方法实现移除对象
          setAttr(re[i][1],'disable','true');
          setAttr(re[i][1],'style.display','none'); 
        }
        if(re
[i][0] == 4) alert(re[i][1]
);
    
}

}

function setAttr(id,attr,v)
{
//设置属性的方法
    var ob = document.getElementById(id);
    var arrAtt = attr.split(".");
    for(var i=0;i{ob = ob[arrAtt[i]];}

    ob
[arrAtt[i]]
 = 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方式的交互完成..

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

阅读(1646) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~