Computed fields in ExtJS Models via convert() functions

Claude Gauthier from Sencha showed us today an elegant way of using convert() method of Ext.data.Model to emulate computed fields.

And since Farata is working on the automation of the creation of the CRUD application with JS clients (the Beta version of CDBJs will be released later this month) this was very appreciated. Ability to use smart Data Transfer Object is crucial. Java and AS3 DTO allow creation of computed fields and we were looking for a similar feature in the ExtJS framework.

In the example below, fullName is a concatenation of lastName and firstName:

Ext.define('Sample.model.User', {
    extend: 'Ext.data.Model',
    fields: [
       {   name:'id', type:'string'},
       {   name:'firstName', type:'string'},
       {   name:'lastName', type:'string'},
       {   name:'fullName', type:'string',
           convert: function (newValue, model) {
               return model.get('lastName') + ',  ' + model.get('firstName');
         }
       }
    ]
});

The only issue here is that, until you perform model.set('fullName', anyValue) ( or least model.set('fullName')) the value of fullName field might be out of sync, as shown below:
var user = Ext.create('Sample.model.User',   {   firstName:'Claude', lastName:'Gauthier'});
console.log(user.fullName); // Gauthier, Claude
user.set('firstName', 'Victor');
console.log(user.fullName); // Gauthier, Claude!
user.set('fullName');
console.log(user.fullName); // Gauthier, Victor

Can we enforce the user.set(‘fullName’) inside the model definition?
Yes, we can. To do that, add the following member function to the model:

[quickcode:noclick]set: function(fieldName, value) {
this.callParent(arguments);
if (fieldName===’firstName’ || fieldName===’lastName’) {
this.set(‘fullName’);
}
}[/quickcode]

Effectively you override the set() of the Ext.data.Model forcing it to recalculate the value of the fullName every time when either firstName or lastName get changed.
And, if the model is joined to a Store, by virtue of this enforced set() the Store will get notified as well.

Thank you, Ext JS for being easily extensible!

Ext.define('Sample.model.User', {
    extend: 'Ext.data.Model',
    fields: [
       {   name:'id', type:'string'},
       {   name:'firstName', type:'string'},
       {   name:'lastName', type:'string'},
       {   name:'fullName', type:'string',
           convert: function (newValue, model) {
               return model.get('lastName') + ',  ' + model.get('firstName');
         }
       }
    ],
    set: function(fieldName, value) {
      this.callParent(arguments);
      if (fieldName==='firstName' || fieldName==='lastName') {
        this.set('fullName');
      }
    }
});

Victor