-
12 Aug 2011 2:50 PM #1
Answered: single dimensional array in store
Answered: single dimensional array in store
Is there a way to do this? I've searched around and saw this, but it doesn't work in 4.0.
http://www.sencha.com/forum/showthre...ensional+array
This is what the server returns that the store has to load in.Code:Ext.define('Job', { extend: 'Ext.data.Model', fields: [{name: 'job'}] }); var jobs_store = Ext.create('Ext.data.ArrayStore', { model: 'Job', proxy: { type: 'ajax', url: '/test', reader: 'array' } });
I've tried all sorts of different store configurations and nothing seems to work. Any ideas?Code:["test1","test2","test3"]
-
Best Answer Posted by mberrie
Solution 1 - use loadData && expandData=true
Code:var data = ['val1', 'val2', 'val3']; Ext.define('JobA', { extend: 'Ext.data.Model', fields: [ {name: 'job'} ] }); Ext.onReady(function() { var store = Ext.create('Ext.data.ArrayStore', { model: 'JobA', data: data, expandData: true // this is tied to ArrayStore#loadData only }); store.loadData(data); store.each(function(item) { console.log(item.get('job')); }) });
Solution 2 - use convert in field definition
Solution 3 - use a custom Reader & extractorCode:var data = ['val1', 'val2', 'val3']; Ext.define('Job', { extend: 'Ext.data.Model', fields: [ {name: 'job', convert: function(value, record) { return record.raw; }} ] }); Ext.onReady(function() { var store = Ext.create('Ext.data.ArrayStore', { model: 'JobB', data: data, }); store.each(function(item) { console.log(item.get('job')); }) });
Code:Ext.define('Ext.data.reader.FlatArray', { extend: 'Ext.data.reader.Json', alias: 'reader.flatarray', buildExtractors: function() { this.callParent(arguments); if(this.model.prototype.fields.items.length > 1) { throw new Error('FlatArray does not support more than one field! ' + 'Check your Model definition for ' + this.model.$className); } this.extractorFunctions = [ (function(data) { return data; }) ]; } });
Solution 4 - use a custom Reader that restructures the input array
This could also support a model with multiple fields (if that makes sense?)
Code:var data = ['Record1.Val1', 'Record1.Val2', 'Record2.Val1', 'Record2.Val2', 'Record3.Val1', 'Record3.Val2']; Ext.define('Ext.data.reader.FlatArray', { extend: 'Ext.data.reader.Json', alias: 'reader.flatarray', getData: function(root) { var fields = this.model.prototype.fields.items, fieldsCount = fields.length, records = []; var count = 0; // total number of records for (var i = 0; i < root.length; i += fieldsCount) { var data = {}; for (var j = 0; j < fieldsCount; j++) { var field = fields[j]; var fieldIdx = field.mapping || j; data[field.name] = root[count * fieldsCount + fieldIdx]; } records.push(data); count++; } return records; } }); Ext.define('Job', { extend: 'Ext.data.Model', fields: [ 'id', 'job' ], proxy: { type: 'memory', reader: 'flatarray', data: data } }); Ext.onReady(function() { // code goes here // note: ArrayStore will setup a memory proxy for us with reader: 'array' var store = Ext.create('Ext.data.Store', { model: 'Job' }); store.on('load', function() { store.each(function(item) { console.log(item.get('id') + ' / ' + item.get('job')); }); }, this); store.load(); });
-
13 Aug 2011 1:02 AM #2
Solution 1 - use loadData && expandData=true
Code:var data = ['val1', 'val2', 'val3']; Ext.define('JobA', { extend: 'Ext.data.Model', fields: [ {name: 'job'} ] }); Ext.onReady(function() { var store = Ext.create('Ext.data.ArrayStore', { model: 'JobA', data: data, expandData: true // this is tied to ArrayStore#loadData only }); store.loadData(data); store.each(function(item) { console.log(item.get('job')); }) });
Solution 2 - use convert in field definition
Solution 3 - use a custom Reader & extractorCode:var data = ['val1', 'val2', 'val3']; Ext.define('Job', { extend: 'Ext.data.Model', fields: [ {name: 'job', convert: function(value, record) { return record.raw; }} ] }); Ext.onReady(function() { var store = Ext.create('Ext.data.ArrayStore', { model: 'JobB', data: data, }); store.each(function(item) { console.log(item.get('job')); }) });
Code:Ext.define('Ext.data.reader.FlatArray', { extend: 'Ext.data.reader.Json', alias: 'reader.flatarray', buildExtractors: function() { this.callParent(arguments); if(this.model.prototype.fields.items.length > 1) { throw new Error('FlatArray does not support more than one field! ' + 'Check your Model definition for ' + this.model.$className); } this.extractorFunctions = [ (function(data) { return data; }) ]; } });
Solution 4 - use a custom Reader that restructures the input array
This could also support a model with multiple fields (if that makes sense?)
Code:var data = ['Record1.Val1', 'Record1.Val2', 'Record2.Val1', 'Record2.Val2', 'Record3.Val1', 'Record3.Val2']; Ext.define('Ext.data.reader.FlatArray', { extend: 'Ext.data.reader.Json', alias: 'reader.flatarray', getData: function(root) { var fields = this.model.prototype.fields.items, fieldsCount = fields.length, records = []; var count = 0; // total number of records for (var i = 0; i < root.length; i += fieldsCount) { var data = {}; for (var j = 0; j < fieldsCount; j++) { var field = fields[j]; var fieldIdx = field.mapping || j; data[field.name] = root[count * fieldsCount + fieldIdx]; } records.push(data); count++; } return records; } }); Ext.define('Job', { extend: 'Ext.data.Model', fields: [ 'id', 'job' ], proxy: { type: 'memory', reader: 'flatarray', data: data } }); Ext.onReady(function() { // code goes here // note: ArrayStore will setup a memory proxy for us with reader: 'array' var store = Ext.create('Ext.data.Store', { model: 'Job' }); store.on('load', function() { store.each(function(item) { console.log(item.get('id') + ' / ' + item.get('job')); }); }, this); store.load(); });
-
15 Aug 2011 11:44 AM #3
Thanks for the many solutions mberrie!! All were greatly appreciated. I ended up using solution #2 which works great! Thanks again!
-
13 Mar 2012 12:08 PM #4
I tried solution #2 but its not working for me. I mean it works if I specify data in arrayStore but as sooon as i replace data with ajax proxy it stopped working.
Here is my code
Model is
Ext.define('CCAdmin.model.Authority', {
extend: 'Ext.data.Model',
fields: [
{name: 'privileges', convert: function(value, record) {
return record.raw;
}
}
]
});
store is
Ext.define('CCAdmin.store.Authority', {
extend: 'Ext.data.ArrayStore',
id: 'Authority',
autoLoad: false,
model: 'CCAdmin.model.Authority',
// data:data
proxy: {
type: 'ajax',
url : 'resources/data/Priviliges.js',
}
});
my Privileges.js file
['val1', 'val2', 'val3']
I am getting below error
records is undefined
[IMG]chrome://firebug/content/blank.gif[/IMG] length = records.length;ext-all-dev.js (line 68136)
Then in main app.js i am loading the store. Please let me know if I am doing anything wring here.
-
20 Aug 2012 1:55 AM #5
Page to be bookmarked. Thank you. Works perfect.


Reply With Quote