代码改变世界

Sencha Touch 数据层篇 Proxy(下)

2012-03-20 15:22  威老  阅读(6333)  评论(4编辑  收藏  举报

服务端代理

服务端代理,有传统的Ajax异步代理,支持跨域请求的JsonP代理(需要服务端支持)。其中Ajax代理和JsonP代理都需要配置url来指明服务器的API接口地址。

Ajax代理(type: 'ajax')

Ajax大家是最熟悉不过了,通过url对服务器的数据进行存取,其数据传输格式为xml或json,下面是一个使用Ajax代理的示例。

Ext.define('User', {
	extend: 'Ext.data.Model',
	fields: ['id', 'name', 'email']
});
var store = Ext.create('Ext.data.Store', {
	model: 'User',
	proxy: {
		type: 'ajax',
		url: 'users.json',
        reader: {
            type: 'json',
            root: 'users'
        }
	}
});
store.load({
    callback: function(records, operation, success){
        console.log(records);
    }
});

在浏览器的控制台观察到以下结果,则表明我们的数据已经被正确地加载并解析了。:



JsonP代理(type: 'jsonp')

JsonP是一个非官方的协议,服务器向客户端回写一段调用客户端函数的js代码,将要返回的数据作为本次函数调用所使用的参数。客户端函数被调用,因此也获得了服务端给出的数据。绕了一圈,却也成功地绕过了浏览器的跨域检测。<

下面是一个Json转JsonP的例子。

//Json格式
{
    users: [
        {
            id: 1,
            name: "Ed Spencer",
            email: "ed@sencha.com"
        }
    ]
}

//JsonP格式
someCallback({
    users: [
        {
            id: 1,
            name: "Ed Spencer",
            email: "ed@sencha.com"
        }
    ]
});

可以看到,JsonP格式只是简单地对Json格式进行了一些修饰,并无太大区别。Json也好,JsonP也罢,它们本质上都只是一串按特定规则形成的字符串罢了。如果你要开发服务端,把要返回的数据处理成Json、JsonP标准的字符串,写到页面中就可以了,如果要更严格些,还需要定义页面MIME类型。

关于JsonP,只需要知道这些对于我们来讲就够用了。因为Sencha Touch已经帮我们隐藏了大部分细节,我们可以像使用Ajax那样来使用JsonP。接下来我们先用现成的api试试效果吧。

这是一个根据邮编返回地名的JsonP服务:
http://www.geonames.org/postalCodeLookupJSON
在浏览器中输入地址
http://www.geonames.org/postalCodeLookupJSON?postalcode=10504&country=US&callback=callback1
我们到以下结果:

callback1({
    postalcodes : [ {
        adminName2 : "Westchester",
        adminCode2 : "119",
        postalcode : "10504",
        adminCode1 : "NY",
        countryCode : "US",
        lng : -73.700942,
        placeName : "Armonk",
        lat : 41.136002,
        adminName1 : "New York"
    } ]
});

根据返回的数据的结构,我们构造出如下模型:

Ext.define('PostalCode', {
    extend : 'Ext.data.Model',
    fields : [ 
        'postalcode',
    	'adminName1',
        'adminName2',
        'adminCode1',
        'adminCode2',
        'countryCode',
        'placeName',
        'lat',
        'lng'
    ]
});

var store = Ext.create('Ext.data.Store', {
    model : 'PostalCode',
    proxy : {
        type : 'jsonp',
        url : 'http://www.geonames.org/postalCodeLookupJSON',
        timeout: 
        reader : {
            type : 'json',
            root : 'postalcodes'
        },
//      callbackKey : 'callback' //默认为'callback',刚好符合这个Api的要求,因此不用改。
    }
});

store.load({
    params : {
        postalcode : '10504',
        country : 'US'
    },
    callback : function(records, operation, success) {
        console.log(records);
    }
});

在浏览器的控制台可以看到输出如下信息:

有时候数据不能被正确加载,此时就需要分析错误代码了。错误信息被包含在operation参数中,我们使用getErro方法获得它,便可以确定错误的类型。错误代码有三个:abort、error以及timeout。

store.load({
    callback: function(records, operation, success){
    	alert(operation.getError());
    }
});

直连代理(type: 'direct')

因为我也不知道direct连接是怎么一回事,所以这个没法写啊,有知道的朋友给介绍一下。