PDA

View Full Version : store each method not working



Cosma
12 Oct 2012, 11:46 AM
Hello,

I've seen plenty of examples of the store.each(fn, scope) in the forum but I can't seem to get it working. I want to load some json data and iterate through all the records in order to create an object that will be added to the "newPanel".

Any help would be appreciated.
Here's my code: (using 4.0.7)



getMonitor: function() {

(tmpStore extends Ext.data.store with autoLoad:false)
var tmpStore = Ext.create('KHS.store.Monitor');
var newPanel = Ext.create('Ext.panel.Panel');

(using store.load({scope:this, callback(fn)}) works but the callback executes AFTER
the return statement at the end of this method)

tmpStore.load();

tmpStore.each(function(records) {

// Create a custom component with the record data and add it to the panel

alert('loadId: ' + records.get('loadId') ....+ other fields
);

newPanel.add(myCustomComponent);

});

return newPanel;

} // getMonitor()



Thanks,
Cosma

scottmartin
12 Oct 2012, 12:49 PM
Is your store valid? Have you checked value of records, etc?



var store = Ext.create('Ext.data.Store', {
storeId : 'simpsonsStore',
fields : ['name', 'email', 'change'],
data : {'items' : [
{ 'name' : 'Lisa', 'email' : 'lisa@simpsons.com', 'change' : 100 },
{ 'name' : 'Bart', 'email' : 'bart@simpsons.com', 'change' : -20 },
{ 'name' : 'Homer', 'email' : 'home@simpsons.com', 'change' : 23 },
{ 'name' : 'Marge', 'email' : 'marge@simpsons.com', 'change' : -11 }
]},
proxy : {
type : 'memory',
reader : {
type : 'json',
root : 'items'
}
}
});

store.each(function(rec) {
console.log(rec.get('change'));
});
‚Äč

Scott.

vietits
12 Oct 2012, 5:02 PM
Because <store>.load() runs asynchronously so you have to wait for its loading completes before accessing its data.

Cosma
23 Oct 2012, 8:54 AM
Thank you both for your help.

@scottmartin, yes, my store and model are correct. I can see the data in chrome's debugger. I can also iterate through the store.data using store.each inside of a callback.

@Vietitis is correct in pointing out the that I have to wait for the async load to complete.

So my question becomes, how do I add my store data to a custom class. I have a class that is meant to create one Ext.button per store record (the data added as text to the button) and then added to a container at runtime.

I'm sure I could use an xtemplate/view, however, I would like to know how add my own store data to a custom view using MVC.

Thank you very much,

Cosma


Here's a look at the code so far...



Ext.define('KHS.model.AsnMonitor', {
extend: 'Ext.data.Model',

fields: [

{name:'status', type: 'string'},
{name:'carrier', type: 'string'},
{name:'destination', type: 'string'},
{name:'loadId', type: 'integer'},
{name:'shipTime', type: 'string'},
{name:'trailerNo', type: 'string'}
] // fields

});


Ext.define('KHS.store.AsnMonitor', {
extend: 'Ext.data.Store',
model: 'KHS.model.AsnMonitor',
autoLoad: false,
interval: 7000,
baseUrlAction: 'asnMonitor',


proxy : {
type: 'ajax',
url : 'Logistics',
extraParams:{'action':'someServletAction'},
reader: {
type: 'json',
root: 'asnMonitor',
totalProperty: 'numResults'
} // reader
} // proxy
});

Cosma
23 Oct 2012, 9:33 AM
Thank you both for your help!!

@scottmartin, yes, my store and model are correct. I can see the data in chrome's debugger. I can also iterate through the store.data using store.each inside of a callback.

@Vietitis is correct in pointing out the that I have to wait for the async load to complete.

So my question becomes, how do I add my store data to a custom class. I have a class that is meant to create one Ext.button per store record (the data added as text to the button) and then added to a container at runtime.

I'm sure I could use an xtemplate/view, however, I would like to know how add my own store data to a custom view using MVC.

Thank you very much,

Cosma



Here's a look at the code so far...(code updated...)




// model:
Ext.define('KHS.model.AsnMonitor', {
extend: 'Ext.data.Model',

fields: [

{name:'status', type: 'string'},
{name:'carrier', type: 'string'},
{name:'destination', type: 'string'},
{name:'loadId', type: 'integer'},
{name:'shipTime', type: 'string'},
{name:'trailerNo', type: 'string'}
] // fields

});

// store:
Ext.define('KHS.store.AsnMonitor', {
extend: 'Ext.data.Store',
model: 'KHS.model.AsnMonitor',
autoLoad: false,

proxy : {
type: 'ajax',
url : 'Logistics',
extraParams:{'action':'someServletAction'},
reader: {
type: 'json',
root: 'asnMonitor',
totalProperty: 'numResults'
} // reader
} // proxy
});

// view:
Ext.define('KHS.view.edi.AsnMonitor', {
extend: 'Ext.container.Container',
alias: 'widget.AsnMonitor',
layout: 'hbox',
align: 'stretch',

initComponent: function() {

var me = this; // keep reference to current scope

this.height = 150;
this.width = '100%';

// the store is created outside of the view and passed in as a config object:
i.e. var asnMonitor = Ext.create('KHS.edi.AsnMonitor,{store:store});
this.store.load({

scope: this.store,
callback: function(records, operation, success) {
this.each(function(records) {
var text = records.get('loadId') + '<br>' +
records.get('status') + '<br>' +
records.get('carrier') + '<br>' +
records.get('destination') + '<br>' +
records.get('shipTime') + '<br>' +
records.get('trailerNo');

var newBtn = Ext.create('Ext.button.Button', {

text: text,
height: 100,
width: 75

}); // this.each(fn...)

// how do I add the newBtn to the "AsnMonitor" container?
// The answer was to use the saved 'this' reference...newkbie mistake!!!
me.add(newBtn);

}); // this.each(fn..)

} // loadStoreHandler

}); // tmpStore.load(...)
this.callParent(arguments);

} // initComponent()

});

damo
23 Oct 2012, 1:40 PM
Do what you was doing before but use the optional callback of the load method.

http://docs.sencha.com/ext-js/4-1/#!/api/Ext.data.Store-method-load

Cosma
24 Oct 2012, 4:19 AM
Hello damo,

I have the callback method coded inside of the initComponent of my view class. The data is there and I'm able to create new buttons. My question is how do I reference the view's container (AsnMonitor) in order to add the newBtn from inside the callback? (Aplogiies for my Noobie questions!!)

Regards,
Cosma

damo
24 Oct 2012, 7:59 AM
Have it handled by the controller class.

The controller has a getter for the store if its part of the stores: [] config option that way you can do something like this.

controller class


refs: [
{
ref: 'AsnMonitor',
selector: 'asnMonitor' // assuming that's the xtype you've given it
}
],

init: function () {
this.mon(this.getYourStore(), 'load', this.onYourStoreLoad, this);
},

onYourStoreLoad: function (store, records, success, options) {
var view = this.getAsnMonitor();
// do the creation logic here for you buttons
}


Now you could instead use the this.control() function and the relayEvents method to pass the stores load event of your view.

Cosma
28 Nov 2012, 8:52 AM
Hi damo,

Great and proper pattern based solution. One change for my project is instead of is using store:[myStore]...getMyStore(), I get a reference to a view and then use it's getStore() method to access the component's store object. I do this because I reuse models, stores, and views. Only the content changes so myView.getStore().load() seems to guarentee I have the correct store instance.


Thanks to everyone's input.

Cosma


Have it handled by the controller class.

The controller has a getter for the store if its part of the stores: [] config option that way you can do something like this.

controller class


refs: [
{
ref: 'AsnMonitor',
selector: 'asnMonitor' // assuming that's the xtype you've given it
}
],

init: function () {
this.mon(this.getYourStore(), 'load', this.onYourStoreLoad, this);
},

onYourStoreLoad: function (store, records, success, options) {
var view = this.getAsnMonitor();
// do the creation logic here for you buttons
}


Now you could instead use the this.control() function and the relayEvents method to pass the stores load event of your view.