Ext.decorate

Sometimes you want to override one of the methods in ExtJS that return a configuration object – let’s use Ext.direct.RemotingProvider’s getCallData as an example, which looks like this:

getCallData: function(t){
  return {
    action: t.action,
    method: t.method,
    data  : t.data,
    type  : 'rpc',
    tid   : t.tid
  };
}

Our aim is to add an ‘authentication_token’ property to the returned object. You could provide the full config object again in an override, but usually you’re overriding to add, remove or change one or two properties and want to leave the rest unmolested. I used to find myself writing a lot of code with this pattern:

//just adds an authentication token to the call data, for context see <a href="http://www.extjs.com/forum/showthread.php?p=378912#post378912">this forum thread</a>
(function() {
  var originalGetCallData = Ext.direct.RemotingProvider.prototype.getCallData;
  
  Ext.override(Ext.direct.RemotingProvider, {
    getCallData: function(t) {
      var defaults = originalGetCallData.apply(this, arguments);
      
      return Ext.apply(defaults, {
        authenticity_token: '<%= form_authenticity_token %>'
      });
    }
  })
})(); 

All we’re really doing here is adding 1 config item – an authenticity_token, but it takes a lot of setup code to make that happen. Check out Ext.decorate:

/**
 * @param {Function} klass The constructor function of the class to override (e.g. Ext.direct.RemotingProvider)
 * @param {String} property The name of the property the function to override is tied to on the klass' prototype
 * @param {Object} config An object that is Ext.apply'd to the usual return value of the function before returning
 */
Ext.decorate = function(klass, property, config) {
  var original = klass.prototype[property];
      override = {};
  
  override[property] = function() {
    var value = original.apply(this, arguments);
    
    return Ext.apply(value, config);
  };
  
  Ext.override(klass, override);
} 

This lets us write the same override like this:

Ext.decorate(Ext.direct.RemotingProvider, 'getCallData', {
  authenticity_token: '<%= form_authenticity_token %>'
}); 

Much nicer, we just tell it what we want with no need for unwieldy boilerplate code. This method doesn’t actually exist in Ext (though it would be good if something similar did), but you could define it yourself as above to keep such code nice and dry.

2 Responses to Ext.decorate

  1. Ryan Mills says:

    Hey Ed,

    Did Ext.decorate make it into ExtJS at all? This is very handy.

    Ryan

  2. Ed Spencer says:

    @Ryan not as such, though the new class system has generally better patterns for achieving things like this – check out http://docs.sencha.com/ext-js/4-0/#!/guide/class_system

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: