2

I have a view which contains a tab control with 2 tabs. I have defined an alias for each tab, in this format:

alias: 'widget.contenttab'

I am trying to access 'contenttab' in the controller but it says it is not defined:

contenttab is not defined

I am trying to set the html content of the tab in a select handler in the controller:

Ext.define('BP.controller.Induction', {
extend: 'Ext.app.Controller',

views: [
    'induction.Binder',
    'induction.LeftPage',
    'induction.RightPage',
],

stores: [
    'Sections',
    'Categories',
    'Tasks'
],

models: [
    'Section',
    'Category',
    'Task'
],


init: function() {
    this.control({
        'grid[xtype=categorygrid]': {
            itemclick: this.onItemClick 
        }
    });
    console.log('Initialized Induction!');
},


onItemClick: function(e, d) {
    console.log(d.data.category_id);
    this.getCategoriesStore().load({params:{'id':d.data.category_id}}, {
        success: function(category) {
            console.log("Category: " + category.get('name'));
        },
        error: function(e) {
            console.log(e);
        }
    });
    contenttab.html = 'test'; // produces error

}
});

The 'contenttab' is within my RightPage view. The line which produces an error ultimately needs to reside within the success callback function - but this isn't getting fired (I have created another question here for that issue Extjs store load success handler not getting fired

Any guidance appreciated, thanks.

Community
  • 1
  • 1
BrynJ
  • 8,322
  • 14
  • 65
  • 89

2 Answers2

5

In your case you should use a ComponentQuery to receive your tab-instances. I guess you will know at least the name of your tab so you can do

var single = Ext.ComponentQuery.query('contenttab[title=YourTabName]')[0];

Or if you need all tabs of that type.

var list = Ext.ComponentQuery.query('contenttab');

The result will always be a array therefor I used the array selector at the first example. You can do this at any point to get a instance. But the more often you do this for the same instance the more I would recommend you to store the instance as local variable. Especially when you are on the way to it within a loop.

The is also the ref property within a controller, which do some things automatically for you. Some example:

refs: [
        {
            ref: 'firstTab',
            selector: 'contenttab[title=YourTabName]'
        }
    ]

This will create a method named getFirstTab() (note the auto camel-case) which refers to your tab (based on the provided query). Note that there are more options like autocreate. I must say, I never used this, but it wraps some things up for you which may be nice at startup.

To answer your last comment of the previous question: Yes this is the correct way to do it.

Community
  • 1
  • 1
sra
  • 23,820
  • 7
  • 55
  • 89
  • Thanks, I will give this a go and see how I get on. – BrynJ Nov 13 '12 at 07:43
  • I've been playing around with this. I had some difficulty in selecting anything but the tab Panel using alias / xtype and the title selector (the only title selector that worked was the title of the panel, rather than each tab). What has worked nicely is to provide an itemId for each tab and use this with query. – BrynJ Nov 13 '12 at 14:22
  • I've had less success setting up refs - using selector of '#myTab' I get undefined warning when calling getMyTab(). Strange. At least I can now get the object by one means :) – BrynJ Nov 13 '12 at 14:31
  • @BrynJ I recommend you to use a custom ident selector that you set by yourself per instance like `cId='firstTab'` instead of setting the id by yourself (if not know exactly what you do setting id'S is a error-prone thing). Now it is important that the tab is created the time you try to find it. It don't need to be visible. You may try it yourself from the console using `Ext.getCmp('name')` for id's or `Ext.ComponentQuery.query('[cId='firstTab']');` and/or for all other selectors. Hope this helps. – sra Nov 13 '12 at 14:42
  • It does indeed, I have followed your advice. I can now output the object to the console, and I can see all properties. The one I'm interested in at the moment is html, and I can set this and confirm it's been set by again outputting to the console, but the tab contents doesn't actually change?! From reading up, I have tried doing myTab.doLayout(), which doesn't generate errors but doesn't seem to do anything. Are the objects copies or references, and what must I do to get the panel to update? – BrynJ Nov 13 '12 at 14:50
  • @BrynJ Ok, that one is simple: the `html` property cannot be set twice or after the component has been rendered (created). It is a one time property, mainly for testing purpose. For any changes you need to get the component `el` and work directly on the DOM. The easy part to test would be to get the tab, call `removeAll()` and afterwards call `add({html:'your content'})` That should work as expected I think. – sra Nov 13 '12 at 14:57
  • Ahh, I see - but I found the update method which seems to work as expected :) However I actually need to add another grid to this panel. How must I set the objects myPanel.items.push()? – BrynJ Nov 13 '12 at 14:58
  • @BrynJ Last part of my last comment describe that topic... use `add()` or `remove()` to add new components. That can be just configs or already created instances. – sra Nov 13 '12 at 15:00
  • Excellent, working great here. I'd buy you a pint if I could :) – BrynJ Nov 13 '12 at 15:07
  • @BrynJ Instead of the pint you could mark this one as answered. I thought it is, isn't it? :) – sra Nov 16 '12 at 15:36
  • It is indeed, and I thought I had! :) – BrynJ Nov 16 '12 at 21:39
2

Providing an alias allows you to use it in Ext.widget('contenttab') method to create an instance of your component. It does not however create a global variable 'contenttab'.

One other thing it does is registers an 'xtype' under 'contenttab' name in the Component Manager. So that you can reference your component by xtype as in

...
items:[ 'contenttab' ],
....

docs for alias: http://docs.sencha.com/ext-js/4-1/#!/api/Ext.Class-cfg-alias and some more examples: http://docs.sencha.com/ext-js/4-1/#!/guide/application_architecture

dbrin
  • 15,525
  • 4
  • 56
  • 83