You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
220 lines
6.5 KiB
JavaScript
220 lines
6.5 KiB
JavaScript
/**
|
|
* @author Don Griffin
|
|
*
|
|
* This singleton manages simulated Ajax responses. This allows application logic to be
|
|
* written unaware that its Ajax calls are being handled by simulations ("simlets"). This
|
|
* is currently done by hooking {@link Ext.data.Connection} methods, so all users of that
|
|
* class (and {@link Ext.Ajax} since it is a derived class) qualify for simulation.
|
|
*
|
|
* The requires hooks are inserted when either the {@link #init} method is called or the
|
|
* first {@link Ext.ux.ajax.Simlet} is registered. For example:
|
|
*
|
|
* Ext.onReady(function () {
|
|
* initAjaxSim();
|
|
*
|
|
* // normal stuff
|
|
* });
|
|
*
|
|
* function initAjaxSim () {
|
|
* Ext.ux.ajax.SimManager.init({
|
|
* delay: 300
|
|
* }).register({
|
|
* '/app/data/url': {
|
|
* stype: 'json', // use JsonSimlet (stype is like xtype for components)
|
|
* data: [
|
|
* { foo: 42, bar: 'abc' },
|
|
* ...
|
|
* ]
|
|
* }
|
|
* });
|
|
* }
|
|
*
|
|
* As many URL's as desired can be registered and associated with a {@link Ext.ux.ajax.Simlet}. To make
|
|
* non-simulated Ajax requests once this singleton is initialized, add a `nosim:true` option
|
|
* to the Ajax options:
|
|
*
|
|
* Ext.Ajax.request({
|
|
* url: 'page.php',
|
|
* nosim: true, // ignored by normal Ajax request
|
|
* params: {
|
|
* id: 1
|
|
* },
|
|
* success: function(response){
|
|
* var text = response.responseText;
|
|
* // process server response here
|
|
* }
|
|
* });
|
|
*/
|
|
Ext.define('Ext.ux.ajax.SimManager', {
|
|
singleton: true,
|
|
|
|
requires: [
|
|
'Ext.data.Connection',
|
|
'Ext.ux.ajax.SimXhr',
|
|
'Ext.ux.ajax.Simlet',
|
|
'Ext.ux.ajax.JsonSimlet'
|
|
],
|
|
|
|
/**
|
|
* @cfg {Ext.ux.ajax.Simlet} defaultSimlet
|
|
* The {@link Ext.ux.ajax.Simlet} instance to use for non-matching URL's. By default, this will
|
|
* return 404. Set this to null to use real Ajax calls for non-matching URL's.
|
|
*/
|
|
|
|
/**
|
|
* @cfg {String} defaultType
|
|
* The default `stype` to apply to generic {@link Ext.ux.ajax.Simlet} configuration objects. The
|
|
* default is 'basic'.
|
|
*/
|
|
defaultType: 'basic',
|
|
|
|
/**
|
|
* @cfg {Number} delay
|
|
* The number of milliseconds to delay before delivering a response to an async request.
|
|
*/
|
|
delay: 150,
|
|
|
|
/**
|
|
* @prop {Boolean} ready
|
|
* True once this singleton has initialized and applied its Ajax hooks.
|
|
* @private
|
|
*/
|
|
ready: false,
|
|
|
|
constructor: function () {
|
|
this.simlets = {};
|
|
},
|
|
|
|
getSimlet: function (url) {
|
|
// Strip down to base URL (no query parameters or hash):
|
|
var me = this,
|
|
index = url.indexOf('?');
|
|
|
|
if (index < 0) {
|
|
index = url.indexOf('#');
|
|
}
|
|
if (index > 0) {
|
|
url = url.substring(0, index);
|
|
}
|
|
|
|
return me.simlets[url] || me.defaultSimlet;
|
|
},
|
|
|
|
getXhr: function (method, url, options, async) {
|
|
var simlet = this.getSimlet(url);
|
|
|
|
if (simlet) {
|
|
return simlet.openRequest(method, url, options, async);
|
|
}
|
|
|
|
return null;
|
|
},
|
|
|
|
/**
|
|
* Initializes this singleton and applies configuration options.
|
|
* @param {Object} config An optional object with configuration properties to apply.
|
|
* @return {Ext.ux.ajax.SimManager} this
|
|
* @markdown
|
|
*/
|
|
init: function (config) {
|
|
var me = this;
|
|
|
|
Ext.apply(me, config);
|
|
|
|
if (!me.ready) {
|
|
me.ready = true;
|
|
|
|
if (!('defaultSimlet' in me)) {
|
|
me.defaultSimlet = new Ext.ux.ajax.Simlet({
|
|
status: 404,
|
|
statusText: 'Not Found'
|
|
});
|
|
}
|
|
|
|
me._openRequest = Ext.data.Connection.prototype.openRequest;
|
|
|
|
Ext.data.Connection.override({
|
|
openRequest: function (options, requestOptions, async) {
|
|
var xhr = !options.nosim &&
|
|
me.getXhr(requestOptions.method, requestOptions.url, options, async);
|
|
if (!xhr) {
|
|
xhr = this.callParent(arguments);
|
|
}
|
|
return xhr;
|
|
}
|
|
});
|
|
|
|
if (Ext.data.JsonP) {
|
|
Ext.data.JsonP.self.override({
|
|
createScript: function (url, params, options) {
|
|
var fullUrl = Ext.urlAppend(url, Ext.Object.toQueryString(params)),
|
|
script = !options.nosim &&
|
|
me.getXhr('GET', fullUrl, options, true);
|
|
|
|
if (!script) {
|
|
script = this.callParent(arguments);
|
|
}
|
|
|
|
return script;
|
|
},
|
|
|
|
loadScript: function (request) {
|
|
var script = request.script;
|
|
if (script.simlet) {
|
|
script.jsonpCallback = request.params[request.callbackKey];
|
|
script.send(null);
|
|
} else {
|
|
this.callParent(arguments);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
return me;
|
|
},
|
|
|
|
openRequest: function (method, url, async) {
|
|
var opt = {
|
|
method: method,
|
|
url: url
|
|
};
|
|
return this._openRequest.call(Ext.data.Connection.prototype, {}, opt, async);
|
|
},
|
|
|
|
/**
|
|
* Registeres one or more {@link Ext.ux.ajax.Simlet} instances.
|
|
* @param {Array/Object} simlet Either a {@link Ext.ux.ajax.Simlet} instance or config, an Array
|
|
* of such elements or an Object keyed by URL with values that are {@link Ext.ux.ajax.Simlet}
|
|
* instances or configs.
|
|
* @markdown
|
|
*/
|
|
register: function (simlet) {
|
|
var me = this;
|
|
|
|
me.init();
|
|
|
|
function reg (one) {
|
|
var simlet = one;
|
|
if (!simlet.isSimlet) {
|
|
simlet = Ext.create('simlet.' + (simlet.stype || me.defaultType), one);
|
|
}
|
|
me.simlets[one.url] = simlet;
|
|
simlet.manager = me;
|
|
}
|
|
|
|
if (Ext.isArray(simlet)) {
|
|
Ext.each(simlet, reg);
|
|
} else if (simlet.isSimlet || simlet.url) {
|
|
reg(simlet);
|
|
} else {
|
|
Ext.Object.each(simlet, function (url, s) {
|
|
s.url = url;
|
|
reg(s);
|
|
});
|
|
}
|
|
|
|
return me;
|
|
}
|
|
});
|