PDA

View Full Version : Noob question: Loading a new view on a button tap



swese44
26 Apr 2011, 9:15 PM
So I've watched all the videos and I've started on my first app, but I'm hung up on loading new views.

Right now my home screen has a bunch of buttons (like the Facebook iPhone app). I'm just setting the buttons to have a different class name and I've styled the buttons with CSS to show each icon as the background image.

That's simple enough. Now I want each button to launch a new view over the top of the home/launcher screen. There will be several of these buttons so I do not want to create instances of them all when the app initializes, I think it would be much more efficient to instantiate one at a time as the corresponding button is tapped, then load the new view on top of the current view.

I'm using the standard MVC pattern, but my "Catches" controller is failing to load up the new view and throws this error:

Uncaught TypeError: Object [object Object] has no method 'setActiveItem'

Here is my app's code, I've stripped it down to just show what is relevant.

Viewport.js view


app.views.Viewport = Ext.extend(Ext.Panel, {
fullscreen: true,
layout: 'fit',
dockedItems: [
{
xtype: 'toolbar',
dock: 'top',
title: 'My Title',
items: [
{
id: 'account',
text: 'Account',
ui: 'normal'
}
]
},
{
xtype: 'toolbar',
dock: 'bottom',
items: [
{
id: 'quickLinks',
text: 'Quick Links',
ui: 'normal'
}
]
}
],
items: [
new Ext.Carousel({
items: [
{
baseCls: 'launcherButton catches',
xtype: 'button',
handler: function (btn, evt) {
console.log("Button '" + btn.text + "' tapped."); // This is properly logged
Ext.dispatch({
controller: app.controllers.catches,
action: 'index',
animation: {type:'pop'}
});
console.log('Just attempted to show Catches view.'); // Controller error prevents this from getting logged
}
}
]
})
],
initComponent: function() {
app.views.Viewport.superclass.initComponent.apply(this, arguments);
}
});



catches.js Controller


app.controllers.catches = new Ext.Controller({
index: function(options) {
console.log('Catches controller about to show index view'); // This is properly logged
app.views.catches = new app.views.Catches();
app.views.viewport.setActiveItem( app.views.catches, options.animation ); // This throws the error
}
});



Catches.js View (this is just dummy content until I can get it to load)


app.views.Catches = Ext.extend(Ext.TabPanel, {
fullscreen: true,
layout: 'fit',
type: 'dark',
items: [{
title: 'Tab 1',
html: '1',
cls: 'card1'
}, {
title: 'Tab 2',
html: '2',
cls: 'card2'
}, {
title: 'Tab 3',
html: '3',
cls: 'card3'
}],
initComponent: function() {
console.log('Catches component initted'); // This is properly logged
}
});


Can somebody point me in the right direction? I'm completely stuck at this point. I'm probably trying to do something very obviously wrong but I can't find any examples to help me get unstuck.

Thanks!

Stoot98
26 Apr 2011, 11:20 PM
The reason you are getting that error is because you are trying to call 'setActiveItem' on the class definition rather than the instance that you created earlier in your app.

If you are going to be using the main Viewport as the container for all your subsequent views then consider storing the instance you create in an app wide variable (for example 'app.Viewport = new app.views.Viewport()') and then when you need to manipulate the viewport (adding new cards, shifting card etc) then you always have a reference to it.

swese44
27 Apr 2011, 12:13 AM
The reason you are getting that error is because you are trying to call 'setActiveItem' on the class definition rather than the instance that you created earlier in your app.

If you are going to be using the main Viewport as the container for all your subsequent views then consider storing the instance you create in an app wide variable (for example 'app.Viewport = new app.views.Viewport()') and then when you need to manipulate the viewport (adding new cards, shifting card etc) then you always have a reference to it.


Thanks for responding Stoot. I forgot to mention that this is my app.js file:


Ext.regApplication({
name: 'app',
launch: function() {
this.launched = true;
this.mainLaunch();
},
mainLaunch: function() {
if (!device || !this.launched) {return;}
console.log('mainLaunch');
this.views.viewport = new this.views.Viewport();
}
});


So app.views.viewport is the instance of app.views.Viewport(), which is the object I am calling setActiveItem() on. Am I not already doing what you suggest, or am I missing something?

Thanks again.

Stoot98
27 Apr 2011, 12:18 AM
Yea, I suppose you are :)

I think you need to define your Viewport Panel with a layout of 'card' so that the setActiveItem method becomes available.

swese44
27 Apr 2011, 10:37 AM
I set the viewport panel and catches view panel to 'card'. Now the setActiveItem() call triggers this error:



Uncaught TypeError: Cannot call method 'getMargin' of undefined sencha-touch-debug.js:18388


:(

Riaz
27 Apr 2011, 5:42 PM
setActiveItem( Ext.Component/Number/Object card, [String/Object cardSwitchAnimation] ) : Ext.Container
Allows you to set the active card in this container. This method is only available if the container uses a CardLayout. Note that a Carousel and TabPanel both get a CardLayout automatically, so both of those components are able to use this method.