Hi, folks!
Want to share my implementation of array types for model fields. Comments are welcome.
Code:
/**
* @class Ext.data.Types
* Additional Types for {@link Ext.data.Field}
*/
(function() {
if (typeof Ext !== 'undefined' && Ext.data && Ext.data.Types)
{
Ext.apply(Ext.data.Types, {
/**
* @property {Object} ARRAY
* Converts the value into an array. Use `arrayType` to specify the type of each
* array item. `arrayType` can be any {@link Ext.data.Types} type.
* `arrayType` can be a string or an object. If `arrayType` is an object,
* it is used as config object for an {@link Ext.data.Field}, though only the properties
* `type`, `convert`, `defaultValue` and `useNull` are relevant. If it is not given,
* {@link Ext.data.Types#AUTO} is used.
*/
ARRAY: {
convert: function(v)
{
var res = [],
defaultValue = this.useNull ? null : res,
i,
len,
at = this.arrayType;
if (!at && this.config && this.config.arrayType) // for Sencha Touch
this.arrayType = at = this.config.arrayType;
// create an Ext.data.Field. The CTOR handles the logic we need
if (!(at instanceof Ext.data.Field))
{
if (Ext.isString(at))
this.arrayType = at = { type: at };
this.arrayType = at = new Ext.data.Field(at);
}
if (v === undefined || v === null)
return defaultValue;
v = Ext.Array.from(v);
for (i = 0, len = v.length; i < len; i++)
res.push(at.convert(v[i]));
return res;
},
sortType: Ext.data.SortTypes.none,
type: 'array'
}
});
var shortCuts = [
/**
* @property {Object} STRING[]
* Converts the value into an array. Each item is converted to {@link Ext.data.Types#STRING string}.
*/
'STRING',
/**
* @property {Object} INT[]
* Converts the value into an array. Each item is converted to {@link Ext.data.Types#INT int}.
*/
'INT',
/**
* @property {Object} INTEGER[]
* @inheritdoc #INT[]
*/
'INTEGER',
/**
* @property {Object} FLOAT[]
* Converts the value into an array. Each item is converted to {@link Ext.data.Types#FLOAT float}.
*/
'FLOAT',
/**
* @property {Object} NUMBER[]
* @inheritdoc #FLOAT[]
*/
'NUMBER'
// DATE and BOOL arrays don't make sense for me
],
i = 0,
len = shortCuts.length;
for (; i < len; i++)
Ext.data.Types[shortCuts[i] + '[]'] = (function(arrayType) {
return {
convert: function() {
this.arrayType = arrayType;
this.convert = Ext.data.Types.ARRAY.convert;
return this.convert.apply(this, arguments);
},
sortType: Ext.data.SortTypes.none,
type: 'array'
};
})(shortCuts[i]);
}
})();
You can use any existing type as type for an array item. Specify it as "arrayType" option. You can also use the shortcuts "string[]", "int[]", "integer[]", "float[]" and "number[]".
Code:
Ext.define('User', {
extend: 'Ext.data.Model',
idProperty: 'id',
fields: [
{name: 'id', type: 'int'},
{name: 'username', type: 'string'},
{name: 'groupIds', type: 'array', arrayType: 'int'}
// can also be {name: 'groupIds', type: 'int[]'}
]
});
I'm sure, the example is not that brilliant. Often you will have model associations of course. But sometimes I have use cases where a sub model is too much and i simply need a simple string array.