PDA

View Full Version : Panel rendering, Text label, JSONStore



Pacos
1 Sep 2011, 5:42 AM
Hello !

I'm facing a conception issue, and all I read online wasn't enough for me to understand how to solve my problem. Here is the situation :

I have created :
- a main panel (a tab panel), which renders to document.body
- one of the tabs contains another panel with a column model
- the first item of this "column panel" (excuse the terminology if it's not exact) contains a dockedItem, in which I just want to display some text
- the first item of this "column panel" also contains a chart, whose data source is a JSONStore

What I want to do is display in the dockedItem is a field from the first record of my JsonStore. Problem :
- if I try to set the text label in the 'load' event of the JsonStore, I have no guarantee that the main panel is already rendered (thus not allowing me to set the text propriety of an object that doesn't exist yet)
- if I try to set the text label directly in the 'text' propriety of the object, I have no guarantee that the store has been loaded and the data is available.

So, I'm searching for a way to somehow combine the two events (afterrender for the Panel and load for the Store) to be able to safely set the text Label. So far nothing was successful.

What is the proper way to achieve something like that ? I think I'm missing something on the global way Panels are rendered, maybe more critical notions. Please correct me if I said anything stupid.

Here is an extract of the onReady function, with the elements I mentionned above :



var dshSumStore = new Ext.data.JsonStore({
//autoDestroy: true,
storeId: 'dshSumStore',
proxy: {
type: 'ajax',
url: 'Controller?action=dslist',
reader: {
type: 'json',
root: 'dshSum',
idProperty: 'id'
}
},
fields: ['id', 'itm', 'bi']
});
dshSumStore.load();

var gaugeBI = Ext.create('Ext.chart.Chart', {
style: 'background:#fff',
animate: {
easing: 'bounceOut',
duration: 500
},
store: dshSumStore,
flex: 1,
width: 300,
height: 200,
axes: [{
type: 'gauge',
position: 'gauge',
minimum: 0,
maximum: 10000,
steps: 4,
margin: -10
}],
series: [{
type: 'gauge',
field: 'bi',
donut: 70,
colorSet: ['#3AA8CB', '#ddd']
}]
});

var colsDashboard = Ext.create('Ext.panel.Panel', {
layout: 'column',
border: 0,
items: [{
items: [gaugeBI],
title: 'Total Buy-ins',
columnWidth: .33,
bodyPadding: 5,
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
items: [{
// this is the text label I'm trying to set with the "bi" field of the first record of dshSumStore
id: 'lblBI',
text: ''
}]
}]
}]
});

var tabs = Ext.create('Ext.tab.Panel', {
renderTo: Ext.getBody(),
width: 1000,
height: 450,
activeTab: 2,
defaults :{
bodyPadding: 10
},
items: [{
items: [colsSession],
title: 'Session'
},{
items: [formTournament],
title: 'Tournament'
},{
items: [colsDashboard],
title: 'Dashboard'
}]
});

Pacos
1 Sep 2011, 6:14 AM
Here is an example of what I tried (but doesn't work) :



var eventRender = 0;
var eventLoad = 0;

function myCallback() {
if (eventRender == 1 && eventLoad == 1) {
//alert('ok');
Ext.get('lblId').text = 'test';
}
};

var dshSumStore = new Ext.data.JsonStore({
autoDestroy: true,
storeId: 'dshSumStore',
proxy: {
type: 'ajax',
url: 'Controller?action=dslist',
reader: {
type: 'json',
root: 'dshSum',
idProperty: 'id'
}
},
fields: ['id', 'itm', 'bi'],
listeners: {
'load' : function() {
eventLoad = 1;
myCallback();
}
}
});
dshSumStore.load();

var gaugeBI = [...]

var colsDashboard = Ext.create('Ext.panel.Panel', {
layout: 'column',
border: 0,
items: [{
items: [gaugeBI],
title: 'Total Buy-ins',
columnWidth: .33,
bodyPadding: 5,
dockedItems: [{
xtype: 'toolbar',
dock: 'bottom',
items: [{
id: 'lblBI',
text: '',
listeners: {
'afterrender': function() {
eventRender = 1;
myCallback();
}
}
}]
}]
}]
});

var tabs = [...]

skirtle
1 Sep 2011, 4:54 PM
Your code attempts to set a text property on the component. This will work but it is too late to change how it is rendered. You could fix it just by using setText() instead but I've knocked together a class that will remove the need for all that global variable stuff your solution was using.

Example usage:


Ext.create('Ext.panel.Panel', {
...
tbar: [
Ext.create('BoundTextItem', {
emptyText: 'No results', // optional
field: 'name', // required
store: store // required
})
]
});


Ext.define('BoundTextItem', {
extend: 'Ext.toolbar.TextItem',

emptyText: '',

initComponent: function() {
this.bindStore(this.store);
this.callParent();
},

bindStore: function(store) {
if (this.store) {
this.mun(this.store, 'datachanged', this.updateText, this);
}

this.store = store;

if (store) {
this.mon(store, 'datachanged', this.updateText, this);
}

this.updateText();
},

updateText: function() {
if (this.store) {
var record = this.store.first();

if (!record) {
this.setText(this.emptyText);
}
else {
this.setText(record.get(this.field));
}
}
}
});

Pacos
2 Sep 2011, 12:47 AM
It works awesomely fine ! Thank you for your help, you made my day :)