PDA

View Full Version : Execute a function in component configuration file



sdd0
31 Dec 2013, 12:31 AM
Hi all,

I have a tab with a loader to autoload a js page(in that tab, renderer: 'component'), loader's url can get a js file which is as below, but it seems that extjs cannot support to execute the function getMytitle(), the page cannot be shown if I use "this.getMytitle()". Is there anything wrong or do I have any other way to achieve that?



{
xtype: 'zyform',
name: 'form1',
id:'zyconnection',
items:[
{
xtype:'zytitlepanel',
html: "Global Setting"
},
{
xtype: 'textfield',
id:'d1',
name: 'email',
ieldLabel: 'Email Address',
vtype: 'email'
},
this.getMytitle()
,{
xtype: 'textfield',
id:'d2',
name: 'email',
fieldLabel: 'Email Address',
vtype: 'email'
}

],
getMytitle: function(){

/* I want to do something before I return the component */

return {
xtype:'zytitlepanel',
html: "my title"
};
}

}

sdd0
1 Jan 2014, 10:38 PM
I might not describe clearly. I put detail files as below:

I have a treepanel, when select event occurs, it runs a for loop to create all tabs for tabpanel (content panel), my tab has a loader, I want it to reload page each time when treepanel is selected or when tabchange event occurs.



Ext.define('zldapp.controller.Treepanel.Treepanel', {
extend: 'Ext.app.Controller',


init: function() {
var myheader = this.header;
this.control({
'treepanel > zytreepanel': {
select: this.onPanelSelect
}
});
},

onPanelSelect: function(selModel, record) {
if (record.get('leaf')) { //it's a leaf
g.start = new Date().getTime();
var tabPanel = Ext.ComponentQuery.query('viewport > panel[region="center"]')[0];

tabs = this.getTabs(record.stores[1].data.items, record.getId());

tabPanel.removeAll();
for(var i=0; i < tabs.length; i++){
tabPanel.add({
title: tabs[i].name,
id: tabs[i].id,
bodyStyle: 'background:none;',
layout: 'fit',
border: false,
margins:'0 5 5 0',
loader: {
url: tabs[i].url,
renderer: 'component',
autoLoad: true,
listeners : {
beforeload : function(loader) {
var form = loader.target;
form.removeAll();
}
}
}
});
}

}
},

getTabs: function(items, id ){
for(var i=0; i < items.length; i++){
if(items[i].data.children != null){
for(var j=0;j < items[i].data.children.length;j++)
{
if (items[i].data.children[j].id == id) {
return items[i].data.children[j].tabs;
}
}
}
}
}

});


I set loader's render attribute as 'component'. The loader will load a js file to tabpanel, the js file is as below:



{
xtype: 'zyform',
name: 'form1',
id:'zyconnection',
items:[
{
xtype:'zytitlepanel',
html: "Global Setting"
},
{
xtype: 'textfield',
id:'d1',
name: 'email',
fieldLabel: 'Email Address',
vtype: 'email'
},
this.getMytitle()
,{
xtype: 'textfield',
id:'d2',
name: 'email',
fieldLabel: 'Email Address',
vtype: 'email'
}

],
getMytitle: function(){

/* I want to do something before I return the component */

return{
xtype:'zytitlepanel',
html: "my title"
};
}

}


I add test code in function "getMytitle()" to return a component configuration, so that some complicated components can be separated from the attribute "items", and I can write extra code before return this item in "getMytitle()". But it seems that it cannot work, but after I removed "this.getMytitle()", the code works fine. Does anyone know what's wrong? Or if I have anyway to achieve that?

sdd0
7 Jan 2014, 1:50 AM
Does anyone know what's wrong with the code?

sdd0
8 Jan 2014, 1:37 AM
I check the source code of Ext.ComponentLoader. About loader's atrribute "Renderer" set as "Component", it says "this renderer can only be used with a {@link Ext.Container} and subclasses". I think that executes a function to get items in a component config is not acceptable.





* ## Component Renderer



* This renderer can only be used with a {@link Ext.Container} and subclasses. It allows for



* Components to be loaded remotely into a Container. The response is expected to be a single/series of



* {@link Ext.Component} configuration objects. When the response is received, the data is decoded



* and then passed to {@link Ext.Container#add}. Using this renderer has the same effect as specifying



* the {@link Ext.Container#items} configuration on a Container.




I find another way to achieve this, in my case, it's necessary for me to do something on items before they are rendered.

Below is the js file got from loader's url, I don't configure items in the beginning. I can call the function "buildItem" later from controller.



{
xtype: 'zyform',
name: 'form1',
buildItem:function(){


/* I can write some code to do something here on items before they are rendered */


var items = [
{
xtype:'zytitlepanel',
html: "Connection Setting"
},
{
xtype: 'textfield',
fieldLabel: 'Name'
}
,{
xtype: 'textfield',
fieldLabel: 'Email Address'
}
];

return items;
}

}


Below is my tabpanel's controller. Before my form is rendered, I get items by the buildItem function and add items into the form.



Ext.define('zldapp.controller.Zytab.Zytab', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'tabpanel': {
tabchange:this.onTabchange
},
'zyform':{
beforerender:this.onBeforeRender
}
});
},
onTabchange: function (tabpanel, tab) {
tab.getLoader().startAutoRefresh(0);
},
onBeforeRender: function (form, eOpts) {
form.add(form.buildItem());
}
});


It works fine, I think this would be my solution. Anyone has comment?