官方论坛找到的确实可行的Proxy
Grid和Form Proxy
1

/**//**2
* http://extjs.com/forum/showthread.php?t=195293
*/4
Ext.namespace("Ext.ux.data");5

6

/**//**7
* @class Ext.ux.data.DWRProxy8
* @extends Ext.data.DataProxy9
* @author loeppky10
* An implementation of Ext.data.DataProxy that uses DWR to make a remote call.11
* @constructor12
* @param {Object} config A configuration object.13
*/14

Ext.ux.data.DWRProxy = function(config)
{15
Ext.apply(this, config); // necessary since the superclass doesn't call apply16
Ext.ux.data.DWRProxy.superclass.constructor.call(this);17
};18

19

Ext.extend(Ext.ux.data.DWRProxy, Ext.data.DataProxy,
{20

21

/**//**22
* @cfg {Function} dwrFunction The DWR function for this proxy to call during load.23
* Must be set before calling load.24
*/25
dwrFunction: null,26
27

/**//**28
* @cfg {String} loadArgsKey Defines where in the params object passed to the load method29
* that this class should look for arguments to pass to the "dwrFunction".30
* The order of arguments passed to a DWR function matters.31
* Must be set before calling load.32
* See the explanation of the "params" parameter for the load function for further explanation.33
*/34
loadArgsKey: 'dwrFunctionArgs',35
36

/**//**37
* Load data from the configured "dwrFunction",38
* read the data object into a block of Ext.data.Records using the passed {@link Ext.data.DataReader} implementation,39
* and process that block using the passed callback.40
* @param {Object} params An object containing properties which are to be used for the request to the remote server.41
* Params is an Object, but the "DWR function" needs to be called with arguments in order.42
* To ensure that one's arguments are passed to their DWR function correctly, a user must either:43
* 1. call or know that the load method was called explictly where the "params" argument's properties were added in the order expected by DWR OR44
* 2. listen to the "beforeload" event and add a property to params defined by "loadArgsKey" that is an array of the arguments to pass on to DWR.45
* If there is no property as defined by "loadArgsKey" within "params", then the whole "params" object will be used as the "loadArgs".46
* If there is a property as defined by "loadArgsKey" within "params", then this property will be used as the "loagArgs".47
* The "loadArgs" are iterated over to build up the list of arguments to pass to the "dwrFunction".48
* @param {Ext.data.DataReader} reader The Reader object which converts the data object into a block of Ext.data.Records.49
* @param {Function} callback The function into which to pass the block of Ext.data.Records.50
* The function must be passed <ul>51
* <li>The Record block object</li>52
* <li>The "arg" argument from the load function</li>53
* <li>A boolean success indicator</li>54
* </ul>55
* @param {Object} scope The scope in which to call the callback56
* @param {Object} arg An optional argument which is passed to the callback as its second parameter.57
*/58

load: function(params, reader, loadCallback, scope, arg)
{59
var dataProxy = this;60

if (dataProxy.fireEvent("beforeload", dataProxy, params) !== false)
{61
var loadArgs = params[this.loadArgsKey] || params; // the Array or Object to build up the "dwrFunctionArgs"62
var dwrFunctionArgs = []; // the arguments that will be passed to the dwrFunction63

if (loadArgs instanceof Array)
{64
// Note: can't do a foreach loop over arrays because Ext added the "remove" method to Array's prototype.65
// This "remove" method gets added as an argument unless we explictly use numeric indexes.66

for (var i = 0; i < loadArgs.length; i++)
{67
dwrFunctionArgs.push(loadArgs[i]);68
}69

} else
{ // loadArgs should be an Object70

for (var loadArgName in loadArgs)
{71
dwrFunctionArgs.push(loadArgs[loadArgName]);72
}73
}74

dwrFunctionArgs.push(
{75

callback: function(response)
{76
// call readRecords verses read because read will attempt to decode the JSON,77
// but as this point DWR has already decoded the JSON.78
var records = reader.readRecords(response);79
dataProxy.fireEvent("load", dataProxy, response, loadCallback);80
loadCallback.call(scope, records, arg, true);81
},82

exceptionHandler: function(message, exception)
{83
// the event is supposed to pass the response, but since DWR doesn't provide that to us, we pass the message.84
dataProxy.fireEvent("loadexception", dataProxy, message, loadCallback, exception);85
loadCallback.call(scope, null, arg, false);86
}87
});88
this.dwrFunction.apply(Object, dwrFunctionArgs); // the scope for calling the dwrFunction doesn't matter, so we simply set it to Object.89

} else
{ // the beforeload event was vetoed90
callback.call(scope || this, null, arg, false);91
}92
}93
});
DWRTree Proxy
1
Ext.namespace('MyApp.tree'); 2
3

/**//** 4
* @constructor 5
* @param {Object} config A config object 6
* @cfg dwrCall the DWR function to call when loading the nodes 7
*/ 8

9

MyApp.tree.DWRTreeLoader = function(config)
{ 10
MyApp.tree.DWRTreeLoader.superclass.constructor.call(this, config); 11
}; 12

13

Ext.extend(MyApp.tree.DWRTreeLoader, Ext.tree.TreeLoader,
{ 14

/**//** 15
* Load an {@link Ext.tree.TreeNode} from the DWR service specified in the constructor. 16
* This is called automatically when a node is expanded, but may be used to reload 17
* a node (or append new children if the {@link #clearOnLoad} option is false.) 18
* @param {Object} node node for which child elements should be retrieved 19
* @param {Function} callback function that should be called before executing the DWR call 20
*/ 21

load : function(node, callback)
{ 22
var cs, i; 23

if (this.clearOnLoad)
{ 24

while (node.firstChild)
{ 25
node.removeChild(node.firstChild); 26
} 27
} 28

if (node.attributes.children && node.attributes.hasChildren)
{ // preloaded json children 29
cs = node.attributes.children; 30

for (i = 0,len = cs.length; i<len; i++)
{ 31
node.appendChild(this.createNode(cs[i])); 32
} 33

if (typeof callback == "function")
{ 34
callback(); 35
} 36

}else if (this.dwrCall)
{ 37
this.requestData(node, callback); 38
}39
}, 40

/**//** 41
* Performs the actual load request 42
* @param {Object} node node for which child elements should be retrieved 43
* @param {Function} callback function that should be called before executing the DWR call 44
*/ 45

requestData : function(node, callback)
{ 46
var callParams = []; 47
var success, error, params, key; 48

49

if (this.fireEvent("beforeload", this, node, callback) !== false)
{ 50

51
success = this.handleResponse.createDelegate(this, [node, callback], 1); 52
error = this.handleFailure.createDelegate(this, [node, callback], 1); 53
params = this.getParams(node); 54

55
// node id is no longer applied as method parameter - see #getParams 56

for (key in params)
{ 57
callParams.push(params[key]); 58
} 59

60

callParams.push(
{callback:success, errorHandler:error}); 61
this.transId = true; 62
this.dwrCall.apply(this, callParams); 63

} else
{ 64
// if the load is cancelled, make sure we notify 65
// the node that we are done 66

if (typeof callback == "function")
{ 67
callback(); 68
} 69
} 70
}, 71
72
73

/**//** 74
* Creates a new tree node. Node will be an AsyncTreeNode if node has children that might be loaded later 75
* @param {Object} attr attributes of this new node 76
*/ 77

createNode : function(attr)
{ 78

if (this.baseAttrs)
{ 79
Ext.applyIf(attr, this.baseAttrs); 80
} 81

if (this.applyLoader !== false)
{ 82
attr.loader = this; 83
} 84

if (typeof attr.uiProvider == 'string')
{ 85
attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider); 86
} 87

88
return(attr.hasChildren ? 89
new MyApp.tree.AsyncTreeNode(attr) : 90
new Ext.tree.TreeNode(attr)); 91
}, 92

93

/**//** 94
* Override this to add custom request parameters. Default adds the node id as first and only parameter 95
*/ 96

getParams : function(node)
{ 97

return
{id:node.id}; 98
}, 99

100

/**//** 101
* Handles a sucessful response. 102
* @param {Object} response data that was sent back by the server that contains the child nodes 103
* @param {Object} node parent node to which child nodes will be appended 104
* @param {Function} callback callback that will be performed after appending the nodes 105
*/ 106

handleResponse : function(response, node, callback)
{ 107
this.transId = false; 108
this.processResponse(response, node, callback); 109
this.fireEvent("load", this, node, response); 110
}, 111

112

/**//** 113
* Handles load error 114
* @param {Object} response data that was sent back by the server that contains the child nodes 115
* @param {Object} node parent node to which child nodes will be appended 116
* @param {Function} callback callback that will be performed after appending the nodes 117
*/ 118

handleFailure : function(response, node, callback)
{ 119
this.transId = false; 120
this.fireEvent("loadexception", this, node, response); 121

if (typeof callback == "function")
{ 122
callback(this, node); 123
} 124
throw "error during tree loading"; 125
}, 126

127

/**//** 128
* Process the response that server sent back via DWR. 129
* @param {Object} response data that was sent back by the server that contains the child nodes 130
* @param {Object} node parent node to which child nodes will be appended 131
* @param {Function} callback callback that will be performed after appending the nodes 132
*/ 133

processResponse : function(response, node, callback)
{ 134
var i, n, nodeCfg, nodeData, assetData, permissionData; 135

try
{ 136

for (i = 0; i<response.length; i++)
{ 137
nodeData = response[i]; 138
//IF YOUR SERVICE DOES NOT RETURN THE NODE DATA IN THE CORRECT FORMAT, CREATE A TREE NODE CONFIG OBJBECT HERE 139

/**//* 140
nodeCfg = { 141
expanded: nodeData.someValue, 142
hasChildren: nodeData.someValue, 143
id: nodeData.id, 144
text: nodeData.name, 145
type: nodeData.type 146
} 147
n = this.createNode(nodeCfg); 148
*/ 149
150
//otherwise, you can just pass the node data on to createNode 151
n = this.createNode(nodeData); 152
153

if (n)
{ 154
node.appendChild(n); 155
} 156
} 157

if (typeof callback == "function")
{ 158
callback(this, node); 159
} 160

} catch(e)
{ 161
this.handleFailure(response); 162
} 163
} 164

165

166
}); 167

168

169

MyApp.tree.AsyncTreeNode = function(config)
{170
MyApp.tree.AsyncTreeNode.superclass.constructor.call(this, config);171
//todo: I don't like this, why not just use Ext.apply or || or something?172

if (typeof config.hasChildren != "undefined")
{173
this.hasChildren = config.hasChildren;174
}175
};176

177

Ext.extend(MyApp.tree.AsyncTreeNode, Ext.tree.AsyncTreeNode,
{});
浙公网安备 33010602011771号