One of the really nice features of ExtJS, to my mind anyway, is the rich model architecture, and how models can be associated with each other. However, the quality can be a bit erratic – certainly, it appears that the HasOne association (which allows a one-to-one relationship) could use some loving, as it isn’t as well developed as the more commonly-used HasMany
Associations are important, even if you’re not using them as a sort of ORM system (which I’m not), because associations are necessary when converting a rich JSON document structure into models. Lots of document structures will contain nested JSON objects, many of which are in a “one-to-one” relationship with the parent. Making the hasOne relationship easier to work with is important.
One immediate problem is the verbosity – so here’s a way, using the overrides functionality of ExtJS, to make it easy to change the name of the association.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Apply an override to the HasOne association, allowing a 'name' parameter to generate the getter, setter, associationKey, and associatedName | |
Ext.override(Ext.data.association.HasOne, { | |
constructor: function(config) { | |
if (config.name ) { | |
Ext.applyIf(config, { | |
getterName: 'get' + Ext.String.capitalize(config.name), | |
setterName: 'set' + Ext.String.capitalize(config.name), | |
associationKey: config.name, | |
associatedName: config.name | |
}) | |
} | |
this.callParent([config]) | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// BEFORE | |
// A JobPosition has a title (a field), a manager (a person), and an occupant (another person) | |
Ext.define('JobPosition', { | |
extend: 'Ext.data.Model', | |
fields: [ | |
{ name: 'title', type: 'string' } | |
], | |
hasOne: [ | |
{ model: 'Person', getterName: 'getManager', setterName: 'setManager', associationKey: 'manager', associatedName: 'manager' }, | |
{ model: 'Person', getterName: 'getOccupant', setterName: 'setOccupant', associationKey: 'occupant', associatedName: 'occupant' } | |
] | |
}) | |
// a Person has a first and last name | |
Ext.define('Person', { | |
extend: 'Ext.data.Model', | |
fields: [ | |
{ name: 'first', type: 'string' }, | |
{ name: 'last', type: 'string' } | |
] | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// AFTER | |
// A JobPosition has a title (a field), a manager (a person), and an occupant (another person) | |
Ext.define('JobPosition', { | |
extend: 'Ext.data.Model', | |
fields: [ | |
{ name: 'title', type: 'string' } | |
], | |
hasOne: [ | |
{ model: 'Person', name: 'manager' }, | |
{ model: 'Person', name: 'occupant' } | |
] | |
}) | |
// a Person has a first and last name | |
Ext.define('Person', { | |
extend: 'Ext.data.Model', | |
fields: [ | |
{ name: 'first', type: 'string' }, | |
{ name: 'last', type: 'string' } | |
] | |
}) |
If you’re using ExtJS, I hope you find this useful; I know I will. I’ve suggested this on the Sencha forums – so with luck, maybe this will be in ExtJS 4.3. 😉