152 lines
4.6 KiB
JavaScript
152 lines
4.6 KiB
JavaScript
/**
|
|
* The DelayedTask class provides a convenient way to "buffer" the execution of a method,
|
|
* performing `setTimeout` where a new timeout cancels the old timeout. When called, the
|
|
* task will wait the specified time period before executing. If during that time period,
|
|
* the task is called again, the original call will be canceled. This continues so that
|
|
* the function is only called a single time for each iteration.
|
|
*
|
|
* This method is especially useful for things like detecting whether a user has finished
|
|
* typing in a text field. An example would be performing validation on a keypress. You can
|
|
* use this class to buffer the keypress events for a certain number of milliseconds, and
|
|
* perform only if they stop for that amount of time.
|
|
*
|
|
* Using {@link Ext.util.DelayedTask} is very simple:
|
|
*
|
|
* //create the delayed task instance with our callback
|
|
* var task = Ext.create('Ext.util.DelayedTask', {
|
|
* fn: function() {
|
|
* console.log('callback!');
|
|
* }
|
|
* });
|
|
*
|
|
* task.delay(1500); //the callback function will now be called after 1500ms
|
|
*
|
|
* task.cancel(); //the callback function will never be called now, unless we call delay() again
|
|
*
|
|
* ## Example
|
|
*
|
|
* @example
|
|
* //create a textfield where we can listen to text
|
|
* var field = Ext.create('Ext.field.Text', {
|
|
* xtype: 'textfield',
|
|
* label: 'Length: 0'
|
|
* });
|
|
*
|
|
* //add the textfield into a fieldset
|
|
* Ext.Viewport.add({
|
|
* xtype: 'formpanel',
|
|
* items: [{
|
|
* xtype: 'fieldset',
|
|
* items: [field],
|
|
* instructions: 'Type into the field and watch the count go up after 500ms.'
|
|
* }]
|
|
* });
|
|
*
|
|
* //create our delayed task with a function that returns the fields length as the fields label
|
|
* var task = Ext.create('Ext.util.DelayedTask', function() {
|
|
* field.setLabel('Length: ' + field.getValue().length);
|
|
* });
|
|
*
|
|
* // Wait 500ms before calling our function. If the user presses another key
|
|
* // during that 500ms, it will be canceled and we'll wait another 500ms.
|
|
* field.on('keyup', function() {
|
|
* task.delay(500);
|
|
* });
|
|
*
|
|
* @constructor
|
|
* The parameters to this constructor serve as defaults and are not required.
|
|
* @param {Function} fn The default function to call.
|
|
* @param {Object} scope The default scope (The `this` reference) in which the function is called. If
|
|
* not specified, `this` will refer to the browser window.
|
|
* @param {Array} args The default Array of arguments.
|
|
*/
|
|
Ext.define('Ext.util.DelayedTask', {
|
|
config: {
|
|
interval: null,
|
|
delay: null,
|
|
fn: null,
|
|
scope: null,
|
|
args: null
|
|
},
|
|
|
|
constructor: function(fn, scope, args) {
|
|
var config = {
|
|
fn: fn,
|
|
scope: scope,
|
|
args: args
|
|
};
|
|
|
|
this.initConfig(config);
|
|
},
|
|
|
|
/**
|
|
* Cancels any pending timeout and queues a new one.
|
|
* @param {Number} delay The milliseconds to delay
|
|
* @param {Function} newFn Overrides the original function passed when instantiated.
|
|
* @param {Object} newScope Overrides the original `scope` passed when instantiated. Remember that if no scope
|
|
* is specified, `this` will refer to the browser window.
|
|
* @param {Array} newArgs Overrides the original `args` passed when instantiated.
|
|
*/
|
|
delay: function(delay, newFn, newScope, newArgs) {
|
|
var me = this;
|
|
|
|
//cancel any existing queued functions
|
|
me.cancel();
|
|
|
|
//set all the new configurations
|
|
|
|
if (Ext.isNumber(delay)) {
|
|
me.setDelay(delay);
|
|
}
|
|
|
|
if (Ext.isFunction(newFn)) {
|
|
me.setFn(newFn);
|
|
}
|
|
|
|
if (newScope) {
|
|
me.setScope(newScope);
|
|
}
|
|
|
|
if (newScope) {
|
|
me.setArgs(newArgs);
|
|
}
|
|
|
|
//create the callback method for this delayed task
|
|
var call = function() {
|
|
me.getFn().apply(me.getScope(), me.getArgs() || []);
|
|
me.cancel();
|
|
};
|
|
|
|
me.setInterval(setInterval(call, me.getDelay()));
|
|
},
|
|
|
|
/**
|
|
* Cancel the last queued timeout
|
|
*/
|
|
cancel: function() {
|
|
this.setInterval(null);
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
* Clears the old interval
|
|
*/
|
|
updateInterval: function(newInterval, oldInterval) {
|
|
if (oldInterval) {
|
|
clearInterval(oldInterval);
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
* Changes the value into an array if it isn't one.
|
|
*/
|
|
applyArgs: function(config) {
|
|
if (!Ext.isArray(config)) {
|
|
config = [config];
|
|
}
|
|
|
|
return config;
|
|
}
|
|
});
|