Sencha Touch 2 : Getting a reference to an auto-instantiated view - sencha-touch-2

I'd like to get a reference to a view from my controller in Sencha Touch 2.
I followed the explanation in this question :
Getting a refernce to an auto-instantiated Sencha Touch 2 view
But still, the render and show function in this.control in my controller never get called.
This is my app.js :
Ext.application({
name: 'App',
appFolder: 'src',
controllers: ['Home'],
launch: function () {
Ext.Viewport.setActiveItem({xtype: 'homeView'});
}
});
This is my view :
Ext.define('App.view.HomeView', {
extend: 'Ext.Panel',
alias : 'widget.homeView',
config: {
html : ['<h1>Sencha Touch Web App</h1>']
},
initialize: function() {
this.callParent();
}
});
and this is my controller :
Ext.define('App.controller.Home', {
extend : 'Ext.app.Controller',
views : ['HomeView'],
init: function() {
this.control({
'homeView' : {
render: function() {
console.log('Render method called!');
},
show: function() {
console.log('Show method called!');
}
}
})
}
});
Does anyone have any idea what I'm doing wrong?
Thanks a lot.
Franziska

The render handler is not called for me either. The way I do it is either use show, which will be called every time the component is showed, or use a custom event for when the view is initialised, e.g.
Ext.define('App.view.HomeView', {
extend: 'Ext.Panel',
alias : 'widget.homeView',
config: {
html : ['<h1>Sencha Touch Web App</h1>']
},
initialize: function() {
this.fireEvent('render');
this.callParent();
}
});

Related

Relative component query selectors

ExtJS 4.1 & DeftJS 0.6.8
The documentation says "References to view components can be established via the control annotation and view-relative component query selectors"
Documentation example:
control: {
submitButton: 'panel > button[text="Submit"]'
}
So in my case I want to get access to a menu's button that is nested like this:
...
extend: 'Ext.tree.Panel',
lid: 'mytreepanel',
dockedItems: [{
xtype: 'toolbar',
lid: 'mybbar',
items: [{
xtype: 'splitbutton',
lid: 'mysplitbutton',
menu: {
lid: 'mymenu',
items: [{
lid: 'createFolder',
text: 'Create folder',
}]
}
}]
}]
My attempts:
control: {
createFolder: {
selector : '[lid=createFolder]',
// selector : 'menu[lid=createFolder]',
// selector : 'mytreepanel > menu[lid=createFolder]',
// selector : 'treepanel > toolbar > splitbutton > menu[lid=createFolder]',
listeners: {
click: 'createFolder'
}
}
}
Nothing worked. Can anyone point me to the right direction?
I don't know in which documentation you found your example (control: { submitButton: 'panel > button[text="Submit"]' }), but it doesn't work for me at all.
By following sencha documentation I've created following controller class:
Ext.define('Pandora.controller.Main', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'[lid=mytreepanel] menu[lid=mymenu] menuitem[lid=createFolder]': {
click: function(){ alert(123); }
}
});
}
});
With this definition of control click is working. Also note how the click handler is attached. You must provide callback, not a string.
The solution was to add mixins: ['Deft.mixin.Controllable'] which I forgot to make the view controllable.
So now everything works fine with:
createFolder: {
selector : '[lid=createFolder]',
listeners: {
click: 'createFolder'
}
}

How to switch a view container using Sencha Touch?

How do I switch views in Sencha Touch? Currently I have a new view being shown, but it looks like it overlays onto the existing one. I think I need to hide the previous or destroy it. I was thinking of maybe using Ext.getCmp("noteslist") but this returns 'undefined' when trying to get the current container. Is this the recommended way of navigating between views or is there a better way?
App
Ext.application({
name: "NotesApp",
controllers: ["NotesController", "TestController"],
views: ["NotesListContainer"],
launch: function () {
var notesListContainer = Ext.create("NotesApp.view.NotesListContainer");
Ext.Viewport.add(notesListContainer);
}
});
Controller:
Ext.define("NotesApp.controller.NotesController", {
extend: "Ext.app.Controller",
views: [
"TestListContainer"
],
config: {
refs: {
newNoteBtn: "#new-note-btn",
saveNoteBtn: "#save-note-btn",
},
control: {
newNoteBtn: {
tap: "onNewNote"
},
saveNoteBtn: {
tap: "onSaveNote"
}
}
},
onNewNote: function () {
console.log("onNewNote");
},
onSaveNote: function () {
console.log("onSaveNote");
Ext.Viewport.add({xtype:'testlist'}).show();
// How do I remove the current one?....
},
launch: function () {
this.callParent();
console.log("launch");
},
init: function () {
this.callParent();
console.log("init");
}
});
View
Ext.define("NotesApp.view.NotesListContainer", {
extend: "Ext.Container",
config: {
items: [{
xtype: "toolbar",
docked: "top",
title: "My Notes",
items: [{
xtype: "spacer"
}, {
xtype: "button",
text: "New",
ui: "action",
id:"new-note-btn"
}, {
xtype: "button",
text: "Save",
ui: "action",
id:"save-note-btn"
}]
}]
}
Using Ext.Viewport.add you only add component to viewport, but not set it as active item. You can use Ext.Viewport.setActiveItem for add component and set it as active item in one call.
Example:
//1
Ext.Viewport.setActiveItem({xtype:'testlist'});
//or 2
//Create and add to viewport
Ext.Viewport.add({xtype:'testlist'});
//set active item by index
Ext.Viewport.setActiveItem(1);
//or 3
var list = Ext.create('NotesApp.view.NotesListContainer', {id : 'noteList'});
Ext.Viewport.add(list);
.....
//In place where you need to show list
Ext.Viewport.setActiveItem(list);
If you want to animate swiching between views then use animateActiveItem(list, {type: 'slide', direction: 'right'}) instead a setActiveItem.
It's how you can work with Ext.Viewport and any container with card layout. In the real application view can be created in one part of app(in the controller, int the app, in the view) and set as active in other part. In this case you need get link to the list by any way and use it in the setActiveItem.
There are two techniques 1 using setActiveItem and the other using navigation view...
Navigation View
Set Active item method:
var view=Ext.Viewport.add({xtype: 'testlist'});
Ext.Viewport.setActiveItem(view);
view.show(); //This is additionally done to fire showAnimation

Sencha touch - Why don't my buttons work?

[SOLVED]
I am following this tutorial link
I have a buttons in my Main view like so
Ext.define('Sencha.view.Main', {
extend: 'Ext.Panel',
config: {
items:[
{
text:'hello',
xtype:'button',
action:'pingHomeBadge',
}
]
}
});
And my main controller looks like
Ext.define('Sencha.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
starButton:'button[action=pingHomeBadge]',
},
control: {
starButton: {
tap:'incrementHomeBadge',
},
}
},
incrementHomeBadge: function() {
alert("hello");
},
});
The button gets displayed but when I click on the button nothing happens. Anybody know what I am doing wrong? I pretty much copy pasted the code from the tutorial. Thanks
I suggest you try this way:
Ext.define('Sencha.controller.Main', {
extend: 'Ext.app.Controller',
config: {
refs: {
// starButton:'button[action=pingHomeBadge]',
},
control: {
'button[action=pingHomeBadge]': {
tap:'incrementHomeBadge',
},
}
},
incrementHomeBadge: function() {
alert("hello");
},
});
Also check whether this controller is getting loaded or not. As in mentioned in the app.js
UPDATE
Actually they are not in your control, but your refs look fine... i dont see anything with your code so i suspect the issue lies elsewhere... why not just compare your source with the source code of the tutorial? http://github.com/senchalearn/Tabs-and-Toolbars

Extjs4 MVC, Add listener to view.Viewport in viewport controller

I want to add 'afterrender' listener to view.Viewport to do something after render viewport.
anybody know how to do this?
My code is,
view.Viewport.js
Ext.define('App.view.Viewport', {
extend: 'Ext.container.Viewport',
alias: 'widget.viewport',
.
.
.
controller.Viewport.js
Ext.define('App.controller.Viewport', {
extend: 'Ext.app.Controller',
init: function (application) {
if (this.inited) {
return;
}
this.inited = true;
//console.log(this.getViewport());
this.getViewport().addListener('load', function () {
console.log('AFTER RENDER'); // it does not work....
});
.
.
.
Thank you!
The MVC Application Architecture guide shows you exactly how to do that.
From the doc:
Ext.define('AM.controller.Users', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'viewport > panel': {
render: this.onPanelRendered
}
});
},
onPanelRendered: function() {
console.log('The panel was rendered');
}
});
I guess if I match this to your code, it will be:
Ext.define('App.controller.Viewport', {
extend: 'Ext.app.Controller',
init: function() {
this.control({
'viewport': {
afterrender: this.onViewportRendered
}
});
},
onViewportRendered: function() {
console.log('The viewport was rendered');
}
});

Switch views with button

I have two views. The User view has some text and a button. I want to use that button to switch to the second view. But i don't know how this works with sencha touch 2. When i press the button on the "UserView" (which is the first view), then i get the following error:
Uncaught Error: SYNTAX_ERR: DOM Exception 12
This is basically how my code looks right now:
app.js
Ext.Loader.setConfig({ enabled: true });
Ext.setup({
viewport: {
autoMaximize: false
},
onReady: function() {
var app = new Ext.Application({
name: 'AM',
controllers: [
'Main'
]
});
}
});
The Main controller
Ext.define('AM.controller.Main', {
extend: 'Ext.app.Controller',
views : ['User'],
init: function() {
this.getUserView().create();
this.control ({
'#new': {
tap: function() {
alert('aaaa');
}
}
});
}
});
And the two views:
Ext.define('AM.view.User', {
extend: 'Ext.Container',
config: {
fullscreen:true,
items: [{
xtype: 'button',
text: 'New',
id: 'new'
}
],
html: 'Testing<br />'
}
});
2nd view
Ext.define('AM.view.New', {
extend: 'Ext.Container',
config: {
fullscreen: true,
html: 'w00t'
}
});
Here is your application written the way it should be. Here are a few notes about the changes I made:
You should call Ext.application instead of Ext.setup when creating your MVC application.
All root views should be defined inside your app.js.
You no longer need to use this.control() in your controllers. You can simply use the control configuration in the config block.
You should define all views in the views config of Ext.application.
Instead of creating the view in init, do it in launch. This is components should be added into the view.
app/view/User.js
Ext.define('AM.view.User', {
extend: 'Ext.Container',
config: {
items: [
{
xtype: 'button',
text: 'New',
id: 'new'
}
],
html: 'Testing<br />'
}
});
app/view/New.js
Ext.define('AM.view.New', {
extend: 'Ext.Container',
config: {
html: 'w00t'
}
});
app/controller/Main.js
Ext.define('AM.controller.Main', {
extend: 'Ext.app.Controller',
config: {
control: {
'#new': {
// On the tap event, call onNewTap
tap: 'onNewTap'
}
}
},
launch: function() {
// When our controller is launched, create an instance of our User view and add it to the viewport
// which has a card layout
Ext.Viewport.add(Ext.create('AM.view.User'));
},
onNewTap: function() {
// When the user taps on the button, create a new reference of our New view, and set it as the active
// item of Ext.Viewport
Ext.Viewport.setActiveItem(Ext.create('AM.view.New'));
}
});
app.js
Ext.application({
name: 'AM',
// Include the only controller
controllers: ['Main'],
// Include all views
views: ['User', 'New'],
// Give the Ext.Viewport global instance a custom layout and animation
viewport: {
layout: {
type: 'card',
animation: {
type: 'slide',
direction: 'left',
duration: 300
}
}
}
});
I also suggest you checkout the great guides over on the Sencha Touch API Docs, as well as checking out the Sencha Forums as they are very active and are a great source of information.