-
8 Feb 2013 8:29 AM #1
Confused on ItemId versus Id when used with controller / componentquery
Confused on ItemId versus Id when used with controller / componentquery
I had thought that a controls id always would work and that only itemId works when the control is either a sibling or child. I've got the code below for a controller that listens for a button click (among other things). It does not respond when the button (continueButtonId) is set as the id property of the button, but the controller does respond when continueButtonId is the itemId of the button.
What am I understanding incorrectly?
Code:Ext.define('RegistrationApp.controller.RegisterSpeakerAttendeeSponsorController', { extend: 'Ext.app.Controller', onRbAttendeeChange: function(field, newValue, oldValue, options) { //console.log('onRbAttendeeChange'); if (newValue == true) { this.rbChoice = 'attendee'; } this.enableContinueButtonIfDisabled(); }, onRbSpeakerChange: function(field, newValue, oldValue, options) { //console.log('onRbSpeakerChange'); if (newValue == true) { this.rbChoice = 'speaker'; } this.enableContinueButtonIfDisabled(); }, onRbSponsorChange: function(field, newValue, oldValue, options) { //console.log('onRbSponsorChange'); if (newValue == true) { this.rbChoice = 'sponsor'; } this.enableContinueButtonIfDisabled(); }, onContinueButtonIdClick: function(button, e, options) { //console.log('continue: ' + this.rbChoice); var tabWizardPanel = Ext.ComponentQuery.query('#TabWizardId')[0]; if (this.rbChoice === 'speaker' || this.rbChoice == 'attendee') { //console.log('speaker or attendee'); tabWizardPanel.setActiveTab(1); } else if (this.rbChoice == 'sponsor') { //console.log('sponsor'); tabWizardPanel.setActiveTab(2); } }, enableContinueButtonIfDisabled: function() { var continueButton = Ext.ComponentQuery.query('#continueButtonId')[0]; if (continueButton.isDisabled()) { continueButton.enable(); } }, init: function(application) { this.control({ "#rbAttendee": { change: this.onRbAttendeeChange }, "#rbSpeaker": { change: this.onRbSpeakerChange }, "#rbSponsor": { change: this.onRbSponsorChange }, "#continueButtonId": { click: this.onContinueButtonIdClick } }); } });
-
8 Feb 2013 8:46 AM #2
Hi :-)
yesterday I read this:
http://docs.sencha.com/architect/2/#!/guide/controllers
and I think, you should do this maybe a second time.
Maybe you have a scope problem. The reference will auto-add you a getter like getReference-Name and the id will be fetched automaticaly. So you have to set the id and not the itemId !
This is different by using an event-handler ! Controller-Actions will use referenced by id.
I hope this is exact - if not - sorry :-)
But I think you are confused and the linked Doc will bring you back to the red line :-)
-
8 Feb 2013 9:13 AM #3
When it's about writing selectors for ComponentQuery, itemId and id are the same, when it's about getting direct items of a container then of course you use itemId.
If an event is not fired then very probably that you have a wrong selector, so you can directly in console to test if you selector is ok and returns some results by using Ext.Component.query(selector).
In your case should work both. Usually when there are more views per controller I write selectors for buttons this way:
it adds some readability to code.Code:'views_xtype #btns_itemId' : {}
-
8 Feb 2013 10:37 AM #4
vadimn,
is 'views_xtype' the name of your controller?
Also, I'm wondering if what I found is a bug. I would have though both would work (itemid and id) in ComponentQuery but the most definitely do not. In my example it is easy to set itemId to blank and Id to the same value and the controller never sees the event.
-
8 Feb 2013 11:00 AM #5
no, that's the xtype of the view which has the button. I'm sure that is not a bug. Post the code of the view with the button. Also better to use itemIds then id's.
-
8 Feb 2013 11:11 AM #6
Here is where the button is. if I change itemId: rbSponsor to id: rbSponsor it does not fire. Does that make sense? please explain further. I really want to understand this (and thanks for your help)
Code:Ext.define('RegistrationApp.view.AttendeeSpeakerOrSponsor', { extend: 'Ext.panel.Panel', alias: 'widget.AttendeeSpeakerOrSponsorAlias', id: 'attendeespeakerorsponsorid', layout: { align: 'stretch', type: 'vbox' }, bodyPadding: 20, title: 'Silicon Valley Code Camp Registration', initComponent: function() { var me = this; Ext.applyIf(me, { items: [ { xtype: 'radiogroup', itemId: 'RadiobuttonGrp', width: 400, defaultType: 'radio', layout: { align: 'stretch', type: 'vbox' }, fieldLabel: '', vertical: false, items: [ { xtype: 'radiofield', itemId: 'rbAttendee', name: 'attendeeType', boxLabel: 'Attendee' }, { xtype: 'radiofield', itemId: 'rbSpeaker', name: 'attendeeType', boxLabel: 'Speaker' }, { xtype: 'radiofield', itemId: 'rbSponsor', name: 'attendeeType', boxLabel: 'Interested In Sponsoring' } ] } ], dockedItems: [ { xtype: 'toolbar', flex: 1, dock: 'bottom', height: 50, itemId: 'ToolBarAttendeeSpeakerSponsor', layout: { pack: 'end', type: 'hbox' }, items: [ { xtype: 'tbseparator' }, { xtype: 'button', disabled: true, itemId: 'continueButtonId', iconAlign: 'right', text: 'Continue' } ] } ] }); me.callParent(arguments); } });
-
8 Feb 2013 12:13 PM #7
Does the
Code:Ext.ComponentQuery.query('#continueButtonId')
return anything ?
-
8 Feb 2013 4:47 PM #8
Even More to be confused about now
Even More to be confused about now
So, sticking to the original topic, the code below does show that doing a componentquery for itemId returns the component, id does not.
Rubbing salt into this wound, it turns out that the component query fails (in some cases) in the compiled version of this same code. I have not yet set up m very simple repro, but I'm thinking this is just buggy code (on sencha's side) but I'd love to be shown wrong (or at least explained to)
Code:Ext.define('MyApp.view.MyViewport', { extend: 'Ext.container.Viewport', initComponent: function() { var me = this; Ext.applyIf(me, { items: [ { xtype: 'panel', title: 'My Panel', items: [ { xtype: 'button', id: 'buttonId', itemId: 'buttonItemId', text: 'hits controller' }, { xtype: 'button', text: 'Does Compent Query of buttonId', listeners: { click: { fn: me.onButtonClick, scope: me } } } ] } ] }); me.callParent(arguments); }, onButtonClick: function(button, e, options) { var componentQueryButtonIdLen = Ext.ComponentQuery.query('#buttonId').length; // returns 0 var componentQueryButtonItemIdLen = Ext.ComponentQuery.query('#buttonItemId').length; // returns 1 alert(componentQueryButtonIdLen + ',' + componentQueryButtonItemIdLen); } });Code:Ext.Loader.setConfig({ enabled: true }); Ext.application({ views: [ 'MyViewport' ], autoCreateViewport: true, name: 'MyApp', controllers: [ 'MyController' ] });Code:Ext.define('MyApp.controller.MyController', { extend: 'Ext.app.Controller', onButtonIdClick: function(button, e, options) { console.log('button click inside controller'); }, init: function(application) { this.control({ "#buttonItemId": { click: this.onButtonIdClick } }); } });
-
9 Feb 2013 1:57 AM #9
You are testing when you have both itemId and id configured ? I see that yes, that may be a reason of the problem, because the selector parser uses filterById method, and within it is used component.getItemId
So if itemId is configured then will be used always no matter if the component has id or not, which explains your results in 'Code:filterById = function(items, id) { // USED IN QUERY PARSER var result = [], i = 0, length = items.length, candidate; for (; i < length; i++) { candidate = items[i]; if (candidate.getItemId() === id) { result.push(candidate); } } return result; }, getItemId : function() { // ABSTRACT COMPONENT return this.itemId || this.id; }onButtonClick'


Reply With Quote