I am very new to Sencha Touch and I'm trying to develop an app which includes a user registration view and a user login view.
The main view has a login button and a registration button.
What I am trying to accomplish is to change views in response to the buttons being tapped.
The following is the code I am using:
Ext.define('MyApp.controller.RegisterForm', {
extend: 'Ext.app.Controller',
requires: ['Ext.data.JsonP'],
config: {
refs: {
mainPage: 'mainpage',
loginForm: 'loginform',
registerForm: 'registerform'
},
control: {
'button[action=UserNewAccount]': {
tap: 'onNewAccount'
},
}
},//config
/**
* respond when new account is requested
*/
onNewAccount: function(event){
/**
* I have tried this ...
*/
this.getLoginForm().add(this.getRegisterForm());
this.getLoginForm().setActiveItem(this.getRegisterForm());
/**
* ... and this
*/
this.getLoginForm().setActiveItem({
xtype: 'registerform'
});
console.log('New account requested: ');
}
});
The onNewAccount function responds just fine. The console.log call executes. The problem is the code above that. I've tried those two different approaches with no success.
What am I doing wrong, and how can I achieve my change of views?
It seems the registerform is not a child component of your loginform. You must call the setActiveItem from the parent container.
this.getMainPage().setActiveItem(this.getRegisterForm());
Related
I need to navigate to another view from a event handler in my code, I do it like this
define(['durandal/system', 'durandal/app', 'durandal/viewLocator', 'plugins/router', 'underscore'],
function (system, app, viewLocator, router, _) {
system.log('starting app');
//>>excludeStart("build", true);
system.debug(true);
//>>excludeEnd("build");
app.title = 'Destiny';
app.configurePlugins({
router: true,
dialog: true,
widget: true,
observable: true
});
router.map('destination', 'viewmodels/destination');
router.activate();
_.delay(function() {
app.start().then(function() {
//Replace 'viewmodels' in the moduleId with 'views' to locate the view.
//Look for partial views in a 'views' folder in the root.
viewLocator.useConvention();
//Show the app by setting the root view model for our application with a transition.
app.setRoot('viewmodels/locationPicker', 'flip');
});
}, 1500);
}
);
Here I define a mapping between my moudle and the router - destination and set root view as another view locationPicker
in my another view locationPicker.js, I navigate to it like this
router.navigate('destination');
from the developer tool, I see that my view model destination.js file is loaded without error, but the view does not change at all. Why is this happening? BTW, I am using the durandal 2.0.1 version
The router plugin is initialized in the call to app.start. Therefore, you're configuring the plugin before initialization, and the configuration isn't being registered. Also, I'm not familiar with your syntax for registering the route. The more standard way is to pass in a list of objects with a route pattern and module id. Please try the following:
define(['durandal/system', 'durandal/app', 'durandal/viewLocator', 'plugins/router'],
function (system, app, viewLocator, router) {
system.log('starting app');
//>>excludeStart("build", true);
system.debug(true);
//>>excludeEnd("build");
app.title = 'Destiny';
app.configurePlugins({
router: true,
dialog: true,
widget: true,
observable: true
});
app.start().then(function() {
router.map([
{ route: 'destination', moduleId: 'viewmodels/destination' }
]).activate();
//Replace 'viewmodels' in the moduleId with 'views' to locate the view.
//Look for partial views in a 'views' folder in the root.
viewLocator.useConvention();
//Show the app by setting the root view model for our application with a transition.
app.setRoot('viewmodels/locationPicker', 'flip');
});
}
I have a view designed like that:
Ext.define('MY.view.NotificationMails', {
extend: 'Ext.grid.Panel',
alias: 'widget.NotificationMailsPanel',
id: 'id-notification-mails-panel',
and I have controller for this view which is:
Ext.define('MY.controller.NotificationMailsController', {
extend: 'Ext.app.Controller',
models: [
'NotificationMailsRecord'
],
stores: [
'NotificationMailsStore'
],
views: [
'NotificationMails'
],
// refs:[{
// ref: 'notificationMails',
// selector: 'mailGrid'
// }],
init: function() {
this.control({
'#id-notification-mails-panel': {
itemclick: this.clickedSomething
}
})
},
and just to make some test and eventually find the problem a simple function definition for itemclick :
clickedSomething: function() {
console.log('Deteceted click');
}
But nothing happens. I tried many variations and still can't get my actions from the view to execute functions in the controller.
The curios thing is that I have several controllers and in most of them everything works as expected but this one and few others - I don't know - maybe I do something wrong, maybe the reason is somewhere else.
thanks
Leron
,
This is weird. I'd try the following: console.log within init() to see if the controller is initialized (you might have forgotten to include it in your app list of controllers).
This is my application architecture.
var loginView = Ext.create('Ext.Panel',{
id: 'LoginView',
.....
});
var homeView = Ext.create('Ext.TabPanel',{
id: 'HomeView',
items: [
{
xtype: 'list',
title: 'Home',
store: Ext.create('TweetStore'),
disableSelection: true,
....
},
{
title: 'Reply',
....
},
{
title: 'DM',
....
}
]
});
var mainView = Ext.create('Ext.Panel',{
id: 'MainView',
layout: 'card',
items: [ loginView, mainView ]
});
Ext.define('TweetStore', {
extend: 'Ext.data.Store',
config: {
fields: ...
pageSize: 25,
autoLoad: true,
proxy: {
type: 'ajax',
url: '/home',
pageParam: 'page',
limitParam: 'count',
reader: {
type: 'json'
}
}
}
});
There are two panels in MainView. LoginView is a login page where user input his username and password. When the authorization succeed, the second panel HomeView shows.
My questions:
I want the data in TweetStore to be loaded after the authorization, that is, when the HomeView shows, the data begins to load. But the show event is triggered even the
panel is still hidden. What event should I catch.
When the application starts, I want to send a ajax request to check whether the user is login, if true, the LoginView hide and the HomeView shows. In which event should I check this?
Q. 1) You should listen for painted() event.
Fires whenever this Component actually becomes visible (painted) on
the screen. This is useful when you need to perform 'read' operations
on the DOM element, i.e: calculating natural sizes and positioning.
Q. 2) Send the ajax request for user authentication on initialize() event.
Fires when the component has been initialized
- 1st question:
painted event seems good but in fact, it's terribly full of bugs in current release of Sencha Touch 2, as my experience. Do NOT rely on its existence and documentation.
According to what you've described, it's clear that you want to load your store after a specific event (authorization), so how about firing a custom event after that? For example:
loginForm.fireEvent('authenticated', this) (or any extra-params you need)
then in your controller, just listen to event authenticated on loginForm view.
- 2nd question:
As you said, you want to run some processes right after your application started. So the right place to put your code is in launch() function of your app.js. Just simple.
I have a question regarding the show event.
in my application I'm handling the painted event of my panel like this:
Ext.define('mvcTest.controller.Test', {
extend: 'Ext.app.Controller',
config: {
refs: {
panel: '#testpanel'
},
control:{
panel: {
painted: 'onPainted'
}
}
},
onPainted: function(){
alert('painted');
}
});
the docu say's, that there is also a "show" event, but it get not fired at all:
Ext.define('mvcTest.controller.Test', {
extend: 'Ext.app.Controller',
config: {
refs: {
panel: '#testpanel'
},
control:{
panel: {
show: 'onShow'
}
}
},
onShow: function(comp, obj){
alert('show');
}
});
why this does not work?
i know, alerting is the wrong way, but that's not the question.
thanks,
mike
It seems that there's no mistake in your controller. The key reason may lie in another part of your application but ... ok, according to my experience:
painted event straight-forward. Everytime your view is really rendered on the screen, painted fired up. (Note: painted event fires BEFORE the child components of your view are totally rendered. In another word, painted first, DOM generation second.)
show event does NOT necessarily fire up, especially for the initialization time of your view. show event is something fired up when you firstly somehow hide your view, and show it later.
Just experience, may be variant. But hope it might be helpful for you.
You can't handle 'painted' event in controller, because it is not bubbled up to it.
From sencha docs: This event is not available to be used with event delegation. Instead 'painted' only fires if you explicily add at least one listener to it, due to performance reason.
You can handle it by defining a listener in you panel.
Ext.define('MyApp.view.MyPanel', {
extend: 'Ext.Panel',
config: {
},
listeners: {
painted: function (element, options) {
console.log("I've painted");
}
}
});
But 'show' event can be handled in controller. Check if another part of your application see that controller.
(Have you provided reference to your controller? Is the id of your panel is right?)
I know this is an old thread, but someone might find it useful:
Sencha does not initially fire the event 'show' and 'painted'.
You need to trigger it initially.
Use this code snippet to listen to the events from the controller:
Ext.define('MyApp.view.MyPanel', {
extend: 'Ext.Panel',
config: {
},
listeners: {
painted: function (element, options) {
this.fireEvent('painted', [element, options])
}
}
});
I'm following the ExtJS4.0 MVC Application Architecture walk through and modifying it to my own project as I go to make sure I get things right. So far it's working perfectly. I've just completed the 'Defining a View' section and I'm about to start the 'Controlling the grid' section. Before I do, I want to remove the console.log code as I don't want or need it for my own project. I find I can replace it with an alert message but can't remove it all together without generating an error against ext-all-debug.js.
Here's my functioning code on the controller and the error it's generating after I remove the consol.log function. In the example doc, it's AM.controllers.list.
Ext.define('ChatAgent.controller.queues', {
extend: 'Ext.app.Controller'
, views: [
'queue.list'
]
, init: function() {
this.control({
'viewport > panel': {
render: this.onPanelRendered
}
});
}
, onPanelRendered: function() {
console.log('The panel was rendered');
}
});
The error it generates is:
'fireFn' is null or not an object
All I've removed is:
onPanelRendered: function() {
console.log('The panel was rendered');
}
So why the error???
You need to get rid of the event listener as well. When the render event fires it is trying to call onPanelRendered which doesn't exist anymore.
If you aren't listening for any events, you don't even need to have that entire this.control block. Comment this out and see what happens.
this.control({
'viewport > panel': {
render: this.onPanelRendered
}
});