luckuny

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

话说Ajax访问WebSerivce 那都是说到烂的话题了,但你别真别说,当 Extjs4 遇上WebSerivce 还真是让人够折腾。

首先ExtJS 并没有可以直接访问WebSerivce 的Store或者说proxy,因此你得先自己定义一个:

View Code
 1 Ext.define('Ext.ux.WebServiceAjaxProxy', {
 2     extend: 'Ext.data.proxy.Ajax',
 3     require: 'Ext.data',
 4 
 5     buildRequest: function(operation) {
 6         var params = Ext.applyIf(operation.params || { }, this.extraParams || { }),
 7             request;
 8         params = Ext.applyIf(params, this.getParams(params, operation));
 9         if (operation.id && !params.id) {
10             params.id = operation.id;
11         }
12         //debugger;
13         //就是增加这一行
14         params = Ext.JSON.encode(params);
15         request = Ext.create('Ext.data.Request', {
16             params: params,
17             action: operation.action,
18             records: operation.records,
19             operation: operation,
20             url: operation.url
21         });
22         request.url = this.buildUrl(request);
23         operation.request = request;
24         return request;
25     },
26     headers: {//设置请求头
27         'Content-Type': 'application/json; charset=utf-8'
28     },
29     actionMethods: {
30         create: 'POST',
31         destroy: 'DELETE',
32         read: 'POST',
33         update: 'POST'
34     }
35 });

现在好了,有了自己的proxy,可以访问webService了,接着上我们的Store

View Code
 1 Ext.define('Ext.data.CameraTreeStore', {
 2     extend: 'Ext.data.TreeStore',
 3     nodeParam: 'addressId',
 4     proxy: Ext.create('Ext.ux.WebServiceAjaxProxy', {
 5         url: 'WebService/CameraService.asmx/GetCameraAddress',
 6         extraParams: {
 7         },
 8         reader: {
 9             type: 'json',
10             root: 'd'
11         }
12     })
13 });

再定义一个Ext.tree.panel

 

View Code
 1 Ext.define('view.CameraTree', {
 2     extend: 'Ext.tree.Panel',
 3     store: Ext.create('Ext.data.CameraTreeStore', {}),
 4 
 5     height: '100%',
 6     useArrows: true,
 7     rootVisible: false,
 8     isChecked: [falsefalse],
 9     enableDD: true,
10     root: { text: '列表', id: "" },
11 
12     initComponent: function() {
13         var me = this;
14 
15         me.callParent(arguments);
16     }
17 });

 可能兄弟你会问:到此,大功告成了吧?有什么好难的?不就是定义了自己的一个proxy? 嘿,事件还没完呢,服务器返回的的数据大概是这样子:

[{"id":1,"text":"远市","Layer":0,"children":[],"dataType":"Address","leaf":false}]

你猜这树会是什么样子?竟然是这样:

我这想想啊,这文字显示不出来到底是哈个子原因呢?看样子应该是没有text字段或者该字段为空吧?但我明明是有的啊,好吧,看来只能调试源代码了,折腾了半天终于找到了:

坑爹啊,data.d竟然还是字符串呢,怪不得,但Extjs为何不提示我?这异常处理也做得太不全了吧。行,那只能手工把它再JSON化了。

重写Ext.decode ,参考了jquery的做法的

View Code
 1 Ext.decodeWS = function (data) {
 2     if (typeof data !== "string" || !data) {
 3         return null;
 4     }
 5     var rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g;
 6     data = (data || "").replace(rtrim, "");
 7 
 8     if (/^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
 9             .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
10             .replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) {
11 
12         // Try to use the native JSON parser first
13         var d = window.JSON && window.JSON.parse ?
14             window.JSON.parse(data) :
15             (new Function("return " + data))();
16 //关键是这一点:
17         if (Ext.isString(d.d)) {
18             d.d = Ext.decodeWS(d.d)
19         }
20 
21         return d;
22     } else {
23         throw "Syntax error, unrecognized expression: Invalid JSON: " + data;
24     }
25 };
26 Ext.decode = Ext.decodeWS;

到了这一步,嘿,可爱的树终于出来了,大松一口气啊。可是真的高兴得太早了,当点击展开树的时候,EXTJS马上跳出

折腾啊,FUUUUUUUUUUUUUUUUUUUUUUUUUUU Y.................................................................................

 

好吧,经过各种苦逼的折腾,终于明白为哈了,就因为id,id绝对不可以是数字,如果是数字,那就把它当字符串那样返回:

 

View Code
1 [{"id":"1","text":"远市","Layer":0,"children":[],"dataType":"Address","leaf":false}]

看清楚了,id的值都是1,但有引号和没有引号是不一样,一定要有引号。

 

OK,写完了,乱乱的,总结一下:

1、Extjs请求Webservice首先要在请求的proxy中反序列化参数,并且设置请求头为'application/json; charset=utf-8',这样才可以返回json数据。

2、返回的数据只进行带一次json化是不行的,因为我们需要的数据都包含在data.d里,而进行一次json化d还是字符串,必须对d进行json化。

3、如果返回的数据有id的话,一定不可以设置为数字,需要用引号把它包起来当成字符串。

 

好了,就写这么大,如果有更好的实现办法望赐教!

posted on 2012-02-17 16:04  luckuny  阅读(981)  评论(0编辑  收藏  举报