PDA

View Full Version : Reusable Components



Peter Tierney
14 Jan 2013, 7:55 AM
I am attempting to get ExtJs to use a component multiple times and they not affect each other. I've attached a simple project where two panels are derived from the same object/class and exhibit unexpected behavior. I have a single controller which should only be responding to one of the panels, but appears to be responding to both.


I am fairly new to ExtJs and am still learning how to get it to do more complex apps. I may just not understand how ExtJs does this kind of thing or may have missed a simple parameter. Yes I've read the not helpful documentation, so if your answer is ntfm, then don't bother answering.


Past this problem, there seems to be a conceptual issue I have with what I understand right now. Even if you do create a class and can reuse it, you have to create a controller for each instance of the component. So you get the reusability of view code but not the controller code. This makes maintenance more of a hassle as I would think creating a component would mean it's able to run it's own code separate from other instances without replicating the controller code. This might be a simple misunderstanding of how ExtJs does things so please feel free to enlighten me.


Regards

41268

existdissolve
14 Jan 2013, 10:02 AM
Can you expand upon exactly what it is that you expect to happen and precisely what it is that is happening unexpectedly?

Peter Tierney
14 Jan 2013, 12:18 PM
It's a simple example where combo box populates a text field inside a panel. The containing panel is the class/component I've tried to reuse. When the second panel, containing a second combo box is selected, it fills the first panel's text field. The second panel has no controller listening for it's events so I would expect it to do nothing. I also would expect that I would need a second controller to handle the second instance of the panel.

In the refs section of the controller, I have the following with the expectation that it would only respond to the first panel (snork is the itemId of the instantiated component).



refs: [
{
ref: 'combo',
selector: '#snork > #areaId',
xtype: 'combobox'
},
{
ref: 'result',
selector: '#snork > #areaResult',
xtype: 'textfield'
}
]


Hopefully I explained that in a sensible manner.

existdissolve
14 Jan 2013, 12:25 PM
Ok, I get you. The reason both are responding to the event is because your AreaController (I assume this is one you're talking about...you didn't mention in your posts) has a listener for "combobox". This is going to capture the change events of *any* active instances of components that have an xtype of "combobox".

If you need to treat them separately, you should be more precise in your control definition. So instead of doing:



this.control({
"combobox": {
change: this.onComboboxChange
}
});


You could more precisely target each combo, based on some property of the component (such as name, id, etc):



this.control({
"combobox[name=combo1]": {
change: this.onComboboxChange
},
"combobox[name=combo2]": {
change: this.onComboboxChange2
}
});


This way, you only need the one controller, and you can precisely target the events of only the components you want, without having to sift out those you don't.

existdissolve
14 Jan 2013, 12:27 PM
Also, the component query in the control definition can be really sophisticated. So let's say you have two comboxes with the same "name", but that live in different panels. You can get more granular and still be able to target them individually:




this.control({
"panel[xtype=somecustomxtype] combobox[name=combo1]": {
change: this.onComboboxChange
},
"panel[xtype=anothercustomxtype] combobox[name=combo1]": {
change: this.onComboboxChange2
}
});

Peter Tierney
14 Jan 2013, 12:30 PM
For my own clarity here



combobox[name=combo1]


name above is the name parameter or the itemId?

existdissolve
14 Jan 2013, 12:32 PM
It's just the "name" property. I didn't look if you were using "name", but it's just an example. For thinks like id's, you could do combobox#someid

Peter Tierney
14 Jan 2013, 12:36 PM
Thanks existdissolve, I'll play around some more and see what I find. Any further suggestions are very welcome.

Stormseeker
15 Jan 2013, 10:05 AM
I think this is what you want:


this.control({
'areapanel[itemId="snork"] combobox': {
change: this.onComboboxChange
},
'areapanel[itemId="differentName"] combobox': {
change: this.onComboboxChange2
}
});