-
19 Jul 2011 5:40 AM #1
MVC ref woes in a controller
MVC ref woes in a controller
Hi all,
I'm trying to create a 'simple' tabpanel that contains 3 grids in a border layout. When I change the selection in the first grid, the second grid should update it's data. Basically the same as the OSX Finder.
So, I have a TabPanel, 3 Grids and a Controller that should update a grid based on the selection of another grid. Question is: How can I reference the grids in the controller? I simply can't get it to work.
Here's the first grid:
And here's the controller:Code:Ext.define('Lk.view.grid.SchoolGridPanel', { extend : 'Ext.grid.Panel', alias : 'widget.SchoolGridPanel', requires : ['Lk.store.SchoolStore'], initComponent : function() { this.store = Lk.store.SchoolStore; this.callParent(); }, columns: [{ header : 'ID', dataIndex : 'ID', width : 10, hidden : true },{ ... }], selModel: { selType: 'cellmodel' } });
The controller is instantiated, I can debug the onInit and onRender methods using firebug.Code:Ext.define('Lk.controller.ExplorerController', { extend: 'Ext.app.Controller', refs: [{ ref: 'schoolGridPanel', selector: 'Lk.view.grid.SchoolGridPanel' },{ ... }], init: function() { var p = this.getSchoolGridPanel(); if(p) { alert('SchoolGridPanel found'); } this.onRender({fn: this.onRender, scope:this}); }, onRender: function() { var p = this.getSchoolGridPanel(); if(p) { p.on({ selectionchange: {fn: this.onSchoolSelectionChange, scope: this} }); } }, onSchoolSelectionChange: function(view, selections, options) { alert('Selection changed'); // Edit second grid based on selection of first (SchoolGridPanel). this.getSchoolGroupPanel().store.load(); } });
I've tried various selectors as 'schoolgridpanel', '.schoolgridpanel', 'SchoolGridPanel', '.SchoolGridPanel', but I think the grid is not initialized/rendered/registered and the variable p is always empty.
I like the 'refs' idea, but what am I missing? Should I use uppercase/lowercase?
RonaldoRonald van Raaphorst aka Ronaldo
I'm a freelance software developer in Java, PHP, and ExtJs.
Skyperonald_twensoc
Mailinfo@twensoc.nl
-
19 Jul 2011 2:19 PM #2
So you're not actually ever seeing the grid?
Unless I'm misunderstanding the problem, you may just need to create the grid by adding "forceCreate: true" to your ref or creating the grid in your init method with "Ext.widget(SchoolGridPanel);"
Also, instead of
This might have been more illuminating.Code:var p = this.getSchoolGridPanel(); if(p) { alert('SchoolGridPanel found'); }
Using a breakpoint would have been even quicker. If you're going to try and debug ExtJS with alert statements you might as well save yourself some time and just go jump off a bridge now.Code:var p = this.getSchoolGridPanel(); console.log(typeof(p)); console.log(p);Try the Sencha Learning Center
-
20 Jul 2011 12:58 AM #3
Hi,
Thx for your reply. I'm seeing the grids all right, and they work fine.
The problem is that the controller does not seem to find the references to the grids, which I need to attach an event listener to (selectionchange) *after* the grid has been initialized.
It seems like the controller is created before the grids exist, or I'm using the wrong selector.
And yes, a console.log message works better than an alert
Best regards,
RonaldoRonald van Raaphorst aka Ronaldo
I'm a freelance software developer in Java, PHP, and ExtJs.
Skyperonald_twensoc
Mailinfo@twensoc.nl
-
20 Jul 2011 8:41 AM #4
You are defining the xtype as SchoolGridPanel with alias : 'widget.SchoolGridPanel', so that selector should work.
Have you tried using this.control in your controllers init() method like the examples in the MVC guide?
Code:this.control( { 'SchoolGridPanel' : { selectionchange : function() { console.log('selection changed') } } })Try the Sencha Learning Center
-
20 Jul 2011 11:57 PM #5
Hi,
Yes, I did that. But the panel containing the 3 grids is on a tab, and it has not been rendered before I select that tab. The controller is instantiated on application start, but the panels were not rendered yet.
What does work is this. ExplorerPanel is the panel containing the 3 gridpanels:
Here I instantiate the controller when the panel is rendered, and that seems to work. Here's the working controller:Code:Ext.define('Lk.view.ExplorerPanel', { extend : 'Ext.tab.Panel', alias : 'widget.ExplorerPanel', requires : ['Lk.view.grid.SchoolGridPanel','Lk.view.grid.SchoolGroupGridPanel', ...], initComponent : function() { this.callParent(); this.on('render', this.onRendered, this, {single:true}); }, onRendered: function() { console.log('ExplorerPanel.render'); this.controller = Ext.create('Lk.controller.ExplorerController', {}); }, items: [{ title: 'Explorer', layout: 'border', controllers: [ // <-- This doesn't work but would be great to control 'ExplorerController' // the containing tabs. I don't need an Application wide ], // controller items: [{ xtype: 'SchoolGridPanel', region: 'west', title: 'Scholen', width: 200, ... }, {
Bottom line: Most of the time I need controllers for "complex" orchestrating jobs, but they should only exist if the complex panel is rendered. I'm not opening all windows/panels at once.Code:Ext.define('Lk.controller.ExplorerController', { extend: 'Ext.app.Controller', refs: [{ ref: 'schoolGridPanel', selector: 'SchoolGridPanel' },{ ref: 'schoolGroupGridPanel', selector: 'SchoolGroupGridPanel' },{ ... }], constructor: function(config) { this.callParent(config); // Can't use this because the application is unknown // This controller is not instantiated from the application // this.control({ // 'SchoolGridPanel': { // selectionchange: this.onSchoolSelectionChange // } // }); this.getSchoolGridPanel().getSelectionModel().on({ selectionchange: {fn:this.onSchoolSelectionChange, scope:this} }); }, init: function() { console.log('ExplorerController.init - Not called this way'); }, onSchoolSelectionChange: function(view, selections, options) { console.log('Selection change'); this.getSchoolGroupGridPanel().store.load(); } });
If the containing panel is not rendered, there's no need to instantiate that controller from the application, as the MVC example shows. If the panel is closed, the controller can be disposed of.Ronald van Raaphorst aka Ronaldo
I'm a freelance software developer in Java, PHP, and ExtJs.
Skyperonald_twensoc
Mailinfo@twensoc.nl


Reply With Quote