Ext与ajax

来源:互联网 发布:大数据工程师薪资待遇 编辑:程序博客网 时间:2024/04/28 23:07

Ext与ajax


1 Ext中的ajax
EXT与后台交换数据时,很大程度上依赖于底层实现的Ajax。所谓底层实现,就是说很可能就是我们之前提到的 Prototype、jQuery或YUI中提供的Ajax功能。为了统一接口,EXT在它们的基础上进行了封装,让我们可以用同一种写法“游走”于各种不同的底层实现之间。
1.1 最容易看到的Ext.Ajax
Ext.Ajax的基本用法如下所示。
Ext.Ajax.request({
    url: '07-01.txt',
    success: function(response) {
        Ext.Msg.alert('成功', response.responseText);
    },
    failure: function(response) {
        Ext.Msg.alert('失败', response.responseText);
    },
    params: { name: 'value' }
});
这里调用的是Ext.Ajax的request函数,它的参数是一个JSON对象,具体如下所示。
 url参数表示将要访问的后台网址。
 success参数表示响应成功后的回调函数。
上例中我们直接从response取得返回的字符串,用Ext.Msg.alert显示出来。
 failure参数表示响应失败后的回调函数。
注意,这里的响应失败并不是指数据库操作之类的业务性失败,而是指HTTP返回404或500错误,请不要把HTTP响应错误与业务错误混淆在一起。
 params参数表示请求时发送到后台的参数,既可以使用JSON对象,也可以直接使用"name=value"形式的字符串。
Ext.Ajax直接继承自Ext.data.Connection,不同的是,它是一个单例,不需要用new创建实例,可以直接使用。在使用Ext.data.Connection前需要先创建实例,因为Ext.data. Connection是为了给Ext.data中的各种proxy提供Ajax功能,分配不同的实例更有利于分别管理。Ext.Ajax为用户提供了一个简易的调用接口,实际使用时,可以根据自己的需要进行选择。
1.2 Ext.lib.Ajax是更底层的封装
其实Ext.Ajax和Ext.data.Connection的内部功能实现都是依靠Ext.lib.Ajax来完成的,在Ext.lib.Ajax下面就是各种底层库的Ajax了。如果使用Ext.lib.Ajax实现以上的功能,就需要写成下面的形式,如下面的代码所示。
Ext.lib.Ajax.request(
    'POST',
    '07-01txt',
    {success: function(response){
        Ext.Msg.alert('成功', response.responseText);
    },failure: function(){
        Ext.Msg.alert('失败', response.responseText);
    }},
    'data=' + encodeURIComponent(Ext.encode({name:'value'}))
);
我们可以看到,使用Ext.lib.Ajax时需要传递4个参数,分别为method、url、callback和params。它们的含义与Ext.Ajax中的参数都是一一对应的,唯一没有提到过的method参数表示请求HTTP的方法,它也可以在Ext.Ajax中使用method:'POST'的方式设置。
相对于Ext.Ajax来说,Ext.lib.Ajax有如下几个缺点。
 参数的顺序被定死了,第一个参数是method,第二个参数是url,第三个参数是回调函数callback,第四个参数是params。这样既不容易记忆,也无法省略其中某个不需要的参数。Ext.Ajax中用JSON对象来定义参数,使用起来更灵活。
 在params部分,Ext.lib.Ajax必须使用字符串形式,显得有些笨重。Ext.Ajax则可以在JSON对象和字符串之间随意选择,非常灵活。
比与Ext.Ajax相比,Ext.lib.Ajax的唯一优势就是它可以在EXT 1.x中使用。如果你使用的是EXT 2.0或更高的版本,那么就放心大胆地使用Ext.Ajax吧,它会带给你更多的惊喜。
2 关于scope和createDelegate()
关于JavaScript中this的使用,这是一个由来已久的问题了。我们这里就不介绍它的发展历史了,只结合具体的例子,告诉大家可能会遇到什么问题,在遇到这些问题时EXT是如何解决的。在使用EXT时,最常碰到的就是使用Ajax回调函数时出现的问题,如下面的代码所示。
<input type="text" name="text" id="text">
<input type="button" name="button" id="button" value="button">
现在的HTML 页面中有一个text输入框和一个按钮。我们希望按下这个按钮之后,能用Ajax去后台读取数据,然后把后台响应的数据放到text中。
function doSuccess(response) {
    text.dom.value = response.responseText;
}

Ext.onReady(function(){
    Ext.get('button').on('click', function(){
        var text = Ext.get('text');
        Ext.lib.Ajax.request(
            'POST',
            '08.txt',
            {success:doSuccess},
            'param=' + encodeURIComponent(text.dom.value)
        );
    });
});

在上面的代码中,Ajax已经用Ext.get('text')获得了text,以为后面可以直接使用,没想到回调函数success不会按照你写的顺序去执行。当然,也不会像你所想的那样使用局部变量text。实际上,如果什么都不做,仅仅只是使用回调函数,你不得不再次使用Ext.get('text')重新获得元素,否则浏览器就会报text未定义的错误。
在此使用Ext.get('text')重新获取对象还比较简单,在有些情况下不容易获得需要处理的对象,我们要在发送Ajax请求之前获取回调函数中需要操作的对象,有两种方法可供选择:scope和createDelegate。
 为Ajax设置scope。

 function doSuccess(response) {
     this.dom.value = response.responseText;
 }
 Ext.lib.Ajax.request(
     'POST',
     '08.txt',
     {success:doSuccess,scope:text},
     'param=' + encodeURIComponent(text.dom.value)
 );               

在Ajax的callback参数部分添加一个scope:text,把回调函数的scope指向text,它的作用就是把doSuccess函数里的this指向text对象。然后再把doSuccess里改成this.dom. value,这样就可以了。如果想再次在回调函数里用某个对象,必须配上scope,这样就能在回调函数中使用this对它进行操作了。
 为success添加createDelegate()。

 function doSuccess(response) {
     this.dom.value = response.responseText;
 }
 
 Ext.lib.Ajax.request(
     'POST',
     '08.txt',
     {success:doSuccess.createDelegate(text)},
     'param=' + encodeURIComponent(text.dom.value)
 );

createDelegate只能在function上调用,它把函数里的this强行指向我们需要的对象,然后我们就可以在回调函数doSuccess里直接通过this来引用createDelegate()中指定的这个对象了。它可以作为解决this问题的一个备选方案。
如果让我选择,我会尽量选择scope,因为createDelegate是要对原来的函数进行封装,重新生成function对象。简单环境下,scope就够用了,倒是createDelegate还有其他功能,比如修改调用参数等。