PDA

View Full Version : 2.0 MVC question on application scope



mike lebowski
27 Dec 2011, 1:34 PM
I am new to sencha, never developed in 1.0, but I notice the 1.0 MVC examples seem to allow access to the application object via the application "name", I see samples that do things like

app.controllers.foo or app.views.fooview etc.

However, when I try that same construct in my ST 2.0 MVC app, I get "undefined" errors. For example:

Ext.application({
name: 'app',
controllers: ['Main'],

If somewhere else in my codebase I try to do app.controllers.Main , I get undefined error.

Now maybe there is a simple error on my part, but I have seen some discussion that the MVC story has really changed and when I look at the 2.0 samples I do not see any using the style of object referencing that I show above.

So is that style of referencing the application object no longer valid? Or is it only valid in certain objects like controllers and not views ?

mike lebowski
27 Dec 2011, 1:40 PM
maybe my thread belongs more in the Q&A forum?

I did download the MVC 2.0 sample http://www.sencha.com/forum/showthread.php?162016-Simple-MVC-example and I see that it has this "overrides" Application.js file, which has a comment in it that says

* Override moves the viewport creation till after the controller
* init methods have been fired.
*
* This will also cache the Ext.application instance onto the namespace.
*
* *** NOTE ***
* For PR3, will not be valid after PR3

So, maybe the answer to my original question is that I need to ALSO use this override class in order to have access to the application object by "name" ? Is that what I should do?

estesbubba
27 Dec 2011, 1:41 PM
Use the getters, getController(), getView(), etc.

http://docs.sencha.com/touch/2-0/#!/api/Ext.app.Application

mike lebowski
27 Dec 2011, 2:27 PM
ok, but to use the getters i need a reference to the application instance first. It seems I do not have a reference to the instance.

estesbubba
27 Dec 2011, 2:34 PM
Are you in a controller? If so you should be able to access the application via this.application.

WillBill
28 Dec 2011, 5:33 AM
I found this to be very usefull:
http://blog.falafel.com/blogs/basememara/11-12-15/Building_a_Mobile_Web_App_using_Sencha_Touch_2_and_MVC.aspx

mbritton
27 Jan 2012, 10:35 AM
I still see no definitive answer on how to get a reference to the application instance.

In my use case I don't need Controllers or Models in my application. They exist elsewhere in the architecture and must remain library-agnostic.

It would be nice to have something like:



var app = Ext.getApplication('myApp');


This would allow objects to subscribe to events. In my case I want to subscribe to view events so I can remove coupling from a "mediator" class.

So is there a solution for this?

Thanks in advance!

rdougan
27 Jan 2012, 11:03 AM
Ext.applciation({
name: 'MyApp',

launch: function() {
console.log(MyApp.app); //application instance
}
});

mbritton
27 Jan 2012, 11:11 AM
I'm using Ext inside a generic Javascript Object, one that doesn't extend any Ext classes, so it doesn't have the ability to reference the application through its native properties.

One approach I'm experimenting with is to register a controller with the application, then create a new instance of that controller in my generic Javascript Object as a sort of generic Facade to be used for establishing event bindings between view components and other generic objects.

I'll post back when I have a workable solution.

mbritton
27 Jan 2012, 12:05 PM
Since I'm using a native Javascript port of PureMVC, I ended up storing the application instance in the model. Now I can access it anywhere in my app.

Again, my architecture contains an Ext application and I'm not using Ext's MVC.



/**
* @constructor
* @extends {SimpleCommand}
*/
function ViewPrepCommand(){};


ViewPrepCommand.prototype = new SimpleCommand;
ViewPrepCommand.prototype.constructor = ViewPrepCommand;
ViewPrepCommand.prototype.executed = false;
/** @override */
ViewPrepCommand.prototype.execute = function(note) {
console.log('ViewPrepCommand::execute');

var facade = Facade.getInstance('ApplicationFacade');

// Create the Ext application(s) and pass the facade
Ext.application({
name:'myApp',
shellFacade:facade,
controllers:['EventBinder'],
launch: function () {
console.log('Ext "myApp" launched');

Ext.create('Ext.container.Viewport', {
id : 'viewport',
layout:'fit',
requires: [
'view.extjs.ExtView'
],
items : [{
type:'box',
id : 'container_center',
layout:'fit',
items:[
{
id:'main',
width:300,
height:300,
layout:'border',
type:'panel',
align:'center',
defaults:{margins:'0 0 0 0'},
anchor:'100%',
defaults: {
split: true,

},
items:[
{
id:'west',
collapsible: true,
minSize:200,
maxSize:300,
region:'west',
title:'Navigation',
margins: '0 0 0 0',
layout:'fit',
width:200
},
{
id:'center',
region:'center',
bodyStyle: 'padding:2px',
autoScroll:true,
layout:'fit',
dockedItems:[
{
xtype:'toolbar',
dock:'top',
items:[
{
id:'toggleEditButton',
enableToggle: true,
type:'button',
text:'Toggle Editable',
pressed: false
}
]
}

]
},
{
id:'south',
region:'south',
margins: '0 0 0 0',
},
{
id:'header',
region:'north',
height:80,
margins: '0 0 0 0',
launch:function() {
console.log('header::launch');
}
},
]
}
]
}]
});

var prox = facade.retrieveProxy(StoryProxy.NAME);
prox.applicationInstance = this;


facade.registerMediator( new HeaderMediator( HeaderMediator.NAME, Ext.getCmp('header') ) );
facade.registerMediator( new WestMediator( WestMediator.NAME, Ext.getCmp('west') ) );
facade.registerMediator( new CenterMediator( CenterMediator.NAME, Ext.getCmp('center') ) );

facade.sendNotification(Application.NOTE_APP_READY);
}
});
};

edspencer
27 Jan 2012, 3:20 PM
Wow that's a lot of boilerplate - what does that all do? Getting a reference to your application is simple:



Ext.application({
name: 'MyApp'
});


MyApp.app; // <- reference to the app


PR3 had a very outdated MVC implementation - PR4 is vastly better in that area, hopefully it meets your needs without resorting to third party libraries...

worthlutz
21 Jun 2012, 8:01 AM
... Getting a reference to your application is simple:


Ext.application({
name: 'MyApp'
});

MyApp.app; // <- reference to the app
...

This works outside Ext.application. How about inside?


Ext.application({
name: 'MyApp',
launch: function () {
setTimeout(this.onStartup, 500);
},

onStartup: function () {
console.log('got here');
if (this.callSecondFunction) {
this.callSecondFunction();
} else {
console.log("doesn't exist");
}
},

callSecondFunction: function () {
console.log('can't get here?'); // because onStartup cannot see this function
}
});
What am I doing wrong?

The setTimeout is to wait for Phonegap to be initialized. It seems to not be ready when I want to use a call in the launch function.

Worth

ayee879
22 Jun 2012, 12:31 PM
Your problem is a scoping issue; when it gets to onStartup, this refers to the Window, not to your application.

worthlutz
22 Jun 2012, 4:59 PM
Thanks.

I figured out to do this


Ext.application({



name: 'MyApp',
launch: function () {
setTimeout( Ext.bind(this.onStartup, this), 500);
},
onStartup: function () {
console.log('got here');
if (this.callSecondFunction) {
this.callSecondFunction();
} else {
console.log("doesn't exist");
}
},
callSecondFunction: function () {
console.log('can't get here?'); // because onStartup cannot see this function
}
});


I'm still fuzzy on scope.

Thanks,
Worth