<!DOCTYPE html>
|
<html>
|
<head>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<title>The source code</title>
|
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
|
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
|
<style type="text/css">
|
.highlight { display: block; background-color: #ddd; }
|
</style>
|
<script type="text/javascript">
|
function highlight() {
|
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
|
}
|
</script>
|
</head>
|
<body onload="prettyPrint(); highlight();">
|
<pre class="prettyprint lang-js"><span id='Ext-app-Controller'>/**
|
</span> * Controllers are the glue that binds an application together. All they really do is listen for events (usually from
|
* views) and take some action. Here's how we might create a Controller to manage Users:
|
*
|
* Ext.define('MyApp.controller.Users', {
|
* extend: 'Ext.app.Controller',
|
*
|
* init: function() {
|
* console.log('Initialized Users! This happens before ' +
|
* 'the Application launch() function is called');
|
* }
|
* });
|
*
|
* The init function is a special method that is called when your application boots. It is called before the
|
* {@link Ext.app.Application Application}'s launch function is executed so gives a hook point to run any code before
|
* your Viewport is created.
|
*
|
* The init function is a great place to set up how your controller interacts with the view, and is usually used in
|
* conjunction with another Controller function - {@link Ext.app.Controller#control control}. The control function
|
* makes it easy to listen to events on your view classes and take some action with a handler function. Let's update
|
* our Users controller to tell us when the panel is rendered:
|
*
|
* Ext.define('MyApp.controller.Users', {
|
* extend: 'Ext.app.Controller',
|
*
|
* init: function() {
|
* this.control({
|
* 'viewport > panel': {
|
* render: this.onPanelRendered
|
* }
|
* });
|
* },
|
*
|
* onPanelRendered: function() {
|
* console.log('The panel was rendered');
|
* }
|
* });
|
*
|
* We've updated the init function to use {@link Ext.app.Controller#control control method} to set up listeners on views
|
* in our application. The control method uses the ComponentQuery engine to quickly and easily get references to components
|
* on the page. If you are not familiar with ComponentQuery yet, be sure to check out the
|
* {@link Ext.ComponentQuery documentation}. In brief though, it allows us to pass a CSS-like selector that will find
|
* every matching component on the page.
|
*
|
* In our init function above we supplied 'viewport > panel', which translates to "find me every Panel that is a direct
|
* child of a Viewport". We then supplied an object that maps event names (just 'render' in this case) to handler
|
* functions. The overall effect is that whenever any component that matches our selector fires a 'render' event, our
|
* onPanelRendered function is called.
|
*
|
* ## Event domains
|
*
|
* In Ext JS 4.2, we introduced the concept of event domains. In terms of MVC, an event domain
|
* is one or more base classes that fire events to which a Controller wants to listen. Besides
|
* Component event domain that encompass {@link Ext.Component}-descended Views, Controllers now
|
* can listen to events from data Stores, Ext.Direct Providers, other Controllers, and Ext.globalEvents.
|
* This feature provides a way to communicate between parts of the whole application without the need
|
* to bind controllers together tightly, and allows to develop and test application parts in isolation.
|
*
|
* See usage examples in {@link #listen} method documentation.
|
*
|
* ## Using refs
|
*
|
* One of the most useful parts of Controllers is the ref system. These use the {@link Ext.ComponentQuery} to
|
* make it really easy to get references to Views on your page. Let's look at an example of this now:
|
*
|
* Ext.define('MyApp.controller.Users', {
|
* extend: 'Ext.app.Controller',
|
*
|
* refs: [{
|
* ref: 'list',
|
* selector: 'grid'
|
* }],
|
*
|
* init: function() {
|
* this.control({
|
* 'button': {
|
* click: this.refreshGrid
|
* }
|
* });
|
* },
|
*
|
* refreshGrid: function() {
|
* this.getList().store.load();
|
* }
|
* });
|
*
|
* This example assumes the existence of a {@link Ext.grid.Panel Grid} on the page, which contains a single button to
|
* refresh the Grid when clicked. In our refs array, we set up a reference to the grid. There are two parts to this -
|
* the 'selector', which is a {@link Ext.ComponentQuery ComponentQuery} selector which finds any grid on the page and
|
* assigns it to the reference 'list'.
|
*
|
* By giving the reference a name, we get a number of things for free. The first is the getList function that we use in
|
* the refreshGrid method above. This is generated automatically by the Controller based on the name of our ref, which
|
* was capitalized and prepended with get to go from 'list' to 'getList'.
|
*
|
* The way this works is that the first time getList is called by your code, the ComponentQuery selector is run and the
|
* first component that matches the selector ('grid' in this case) will be returned. All future calls to getList will
|
* use a cached reference to that grid. Usually it is advised to use a specific ComponentQuery selector that will only
|
* match a single View in your application (in the case above our selector will match any grid on the page).
|
*
|
* Bringing it all together, our init function is called when the application boots, at which time we call this.control
|
* to listen to any click on a {@link Ext.button.Button button} and call our refreshGrid function (again, this will
|
* match any button on the page so we advise a more specific selector than just 'button', but have left it this way for
|
* simplicity). When the button is clicked we use out getList function to refresh the grid.
|
*
|
* You can create any number of refs and control any number of components this way, simply adding more functions to
|
* your Controller as you go. For an example of real-world usage of Controllers see the Feed Viewer example in the
|
* examples/app/feed-viewer folder in the SDK download.
|
*
|
* ## Generated getter methods
|
*
|
* Refs aren't the only thing that generate convenient getter methods. Controllers often have to deal with Models and
|
* Stores so the framework offers a couple of easy ways to get access to those too. Let's look at another example:
|
*
|
* Ext.define('MyApp.controller.Users', {
|
* extend: 'Ext.app.Controller',
|
*
|
* models: ['User'],
|
* stores: ['AllUsers', 'AdminUsers'],
|
*
|
* init: function() {
|
* var User, allUsers, ed;
|
*
|
* User = this.getUserModel();
|
* allUsers = this.getAllUsersStore();
|
*
|
* ed = new User({ name: 'Ed' });
|
* allUsers.add(ed);
|
* }
|
* });
|
*
|
* By specifying Models and Stores that the Controller cares about, it again dynamically loads them from the appropriate
|
* locations (app/model/User.js, app/store/AllUsers.js and app/store/AdminUsers.js in this case) and creates getter
|
* functions for them all. The example above will create a new User model instance and add it to the AllUsers Store.
|
* Of course, you could do anything in this function but in this case we just did something simple to demonstrate the
|
* functionality.
|
*
|
* ## Further Reading
|
*
|
* For more information about writing Ext JS 4 applications, please see the
|
* [application architecture guide](#/guide/application_architecture). Also see the {@link Ext.app.Application}
|
* documentation.
|
*
|
* @docauthor Ed Spencer
|
*/
|
Ext.define('Ext.app.Controller', {
|
requires: [
|
'Ext.app.EventBus',
|
'Ext.ModelManager',
|
'Ext.data.StoreManager',
|
'Ext.ComponentManager',
|
'Ext.app.domain.Global',
|
'Ext.app.domain.Component',
|
'Ext.app.domain.Store'
|
],
|
|
uses: [
|
'Ext.app.domain.Controller'
|
],
|
|
mixins: {
|
observable: 'Ext.util.Observable'
|
},
|
|
<span id='Ext-app-Controller-cfg-id'> /**
|
</span> * @cfg {String} id The id of this controller. You can use this id when dispatching.
|
*/
|
|
statics: {
|
<span id='Ext-app-Controller-property-strings'> strings: {
|
</span> model: {
|
getter: 'getModel',
|
upper: 'Model'
|
},
|
|
view: {
|
getter: 'getView',
|
upper: 'View'
|
},
|
|
controller: {
|
getter: 'getController',
|
upper: 'Controller'
|
},
|
|
store: {
|
getter: 'getStore',
|
upper: 'Store'
|
}
|
},
|
|
<span id='Ext-app-Controller-property-controllerRegex'> controllerRegex: /^(.*)\.controller\./,
|
</span>
|
<span id='Ext-app-Controller-method-createGetter'> createGetter: function(baseGetter, name) {
|
</span> return function () {
|
return this[baseGetter](name);
|
};
|
},
|
|
<span id='Ext-app-Controller-method-getGetterName'> getGetterName: function(name, kindUpper) {
|
</span> var fn = 'get',
|
parts = name.split('.'),
|
numParts = parts.length,
|
index;
|
|
// Handle namespaced class names. E.g. feed.Add becomes getFeedAddView etc.
|
for (index = 0; index < numParts; index++) {
|
fn += Ext.String.capitalize(parts[index]);
|
}
|
|
fn += kindUpper;
|
|
return fn;
|
},
|
|
<span id='Ext-app-Controller-method-processDependencies'> /**
|
</span> * This method is called like so:
|
*
|
* Ext.app.Controller.processDependencies(proto, requiresArray, 'MyApp', 'model', [
|
* 'User',
|
* 'Item',
|
* 'Foo@Common.model',
|
* 'Bar.Baz@Common.model'
|
* ]);
|
*
|
* Required dependencies are added to requiresArray.
|
*
|
* @private
|
*/
|
processDependencies: function(cls, requires, namespace, kind, names) {
|
if (!names || !names.length) {
|
return;
|
}
|
|
var me = this,
|
strings = me.strings[kind],
|
o, absoluteName, shortName, name, j, subLn, getterName, getter;
|
|
if (!Ext.isArray(names)) {
|
names = [names];
|
}
|
|
for (j = 0, subLn = names.length; j < subLn; j++) {
|
name = names[j];
|
o = me.getFullName(name, kind, namespace);
|
absoluteName = o.absoluteName;
|
shortName = o.shortName;
|
|
requires.push(absoluteName);
|
getterName = me.getGetterName(shortName, strings.upper);
|
cls[getterName] = getter = me.createGetter(strings.getter, name);
|
|
// Application class will init the controller getters
|
if (kind !== 'controller') {
|
// This marker allows the constructor to easily/cheaply identify the
|
// generated getter methods since they all need to be called to get
|
// things initialized. We use a property name that deliberately does
|
// not work with dot-access to reduce any chance of collision.
|
getter['Ext.app.getter'] = true;
|
}
|
}
|
},
|
|
<span id='Ext-app-Controller-method-getFullName'> getFullName: function(name, kind, namespace) {
|
</span> var shortName = name,
|
sep, absoluteName;
|
|
if ((sep = name.indexOf('@')) > 0) {
|
// The unambiguous syntax is Model@Name.space (or "space.Model@Name")
|
// which contains both the short name ("Model" or "space.Model") and
|
// the full name (Name.space.Model).
|
//
|
shortName = name.substring(0, sep); // "Model"
|
absoluteName = name.substring(sep + 1) + '.' + shortName; // ex: "Name.space.Model"
|
}
|
// Deciding if a class name must be qualified:
|
//
|
// 1 - if the name doesn't contain a dot, we must qualify it
|
//
|
// 2 - the name may be a qualified name of a known class, but:
|
//
|
// 2.1 - in runtime, the loader may not know the class - specially in
|
// production - so we must check the class manager
|
//
|
// 2.2 - in build time, the class manager may not know the class, but
|
// the loader does, so we check the second one (the loader check
|
// assures it's really a class, and not a namespace, so we can
|
// have 'Books.controller.Books', and requesting a controller
|
// called Books will not be underqualified)
|
//
|
else if (name.indexOf('.') > 0 && (Ext.ClassManager.isCreated(name) ||
|
Ext.Loader.isAClassNameWithAKnownPrefix(name))) {
|
absoluteName = name;
|
}
|
else {
|
//<debug>
|
if (!namespace) {
|
Ext.log.warn("Cannot find namespace for " + kind + " " + name + ", " +
|
"assuming it is fully qualified class name");
|
}
|
//</debug>
|
|
if (namespace) {
|
absoluteName = namespace + '.' + kind + '.' + name;
|
shortName = name;
|
}
|
else {
|
absoluteName = name;
|
}
|
}
|
|
return {
|
absoluteName: absoluteName,
|
shortName: shortName
|
};
|
}
|
},
|
|
<span id='Ext-app-Controller-property-application'> /**
|
</span> * The {@link Ext.app.Application} for this controller.
|
*
|
* @property {Ext.app.Application}
|
* @readonly
|
*/
|
application: null,
|
|
<span id='Ext-app-Controller-cfg-models'> /**
|
</span> * @cfg {String/String[]} models
|
* Array of models to require from AppName.model namespace. For example:
|
*
|
* Ext.define("MyApp.controller.Foo", {
|
* extend: "Ext.app.Controller",
|
* models: ['User', 'Vehicle']
|
* });
|
*
|
* This is equivalent of:
|
*
|
* Ext.define("MyApp.controller.Foo", {
|
* extend: "Ext.app.Controller",
|
* requires: ['MyApp.model.User', 'MyApp.model.Vehicle'],
|
*
|
* getUserModel: function() {
|
* return this.getModel("User");
|
* },
|
*
|
* getVehicleModel: function() {
|
* return this.getModel("Vehicle");
|
* }
|
* });
|
*
|
*/
|
|
<span id='Ext-app-Controller-cfg-views'> /**
|
</span> * @cfg {String/String[]} views
|
* Array of views to require from AppName.view namespace and to generate getter methods for.
|
* For example:
|
*
|
* Ext.define("MyApp.controller.Foo", {
|
* extend: "Ext.app.Controller",
|
* views: ['List', 'Detail']
|
* });
|
*
|
* This is equivalent of:
|
*
|
* Ext.define("MyApp.controller.Foo", {
|
* extend: "Ext.app.Controller",
|
* requires: ['MyApp.view.List', 'MyApp.view.Detail'],
|
*
|
* getListView: function() {
|
* return this.getView("List");
|
* },
|
*
|
* getDetailView: function() {
|
* return this.getView("Detail");
|
* }
|
* });
|
*/
|
|
<span id='Ext-app-Controller-cfg-stores'> /**
|
</span> * @cfg {String/String[]} stores
|
* Array of stores to require from AppName.store namespace and to generate getter methods for.
|
* For example:
|
*
|
* Ext.define("MyApp.controller.Foo", {
|
* extend: "Ext.app.Controller",
|
* stores: ['Users', 'Vehicles']
|
* });
|
*
|
* This is equivalent to:
|
*
|
* Ext.define("MyApp.controller.Foo", {
|
* extend: "Ext.app.Controller",
|
*
|
* requires: [
|
* 'MyApp.store.Users',
|
* 'MyApp.store.Vehicles'
|
* ]
|
*
|
* getUsersStore: function() {
|
* return this.getStore("Users");
|
* },
|
*
|
* getVehiclesStore: function() {
|
* return this.getStore("Vehicles");
|
* }
|
* });
|
*/
|
|
<span id='Ext-app-Controller-cfg-refs'> /**
|
</span> * @cfg {Object[]} refs
|
* Array of configs to build up references to views on page. For example:
|
*
|
* Ext.define("MyApp.controller.Foo", {
|
* extend: "Ext.app.Controller",
|
*
|
* refs: [{
|
* ref: 'list',
|
* selector: 'grid'
|
* }],
|
* });
|
*
|
* This will add method `getList` to the controller which will internally use
|
* Ext.ComponentQuery to reference the grid component on page.
|
*
|
* The following fields can be used in ref definition:
|
*
|
* - `ref` - name of the reference.
|
* - `selector` - Ext.ComponentQuery selector to access the component.
|
* - `autoCreate` - True to create the component automatically if not found on page.
|
* - `forceCreate` - Forces the creation of the component every time reference is accessed
|
* (when `get<REFNAME>` is called).
|
* - `xtype` - Used to create component by its xtype with autoCreate or forceCreate. If
|
* you don't provide xtype, an Ext.Component instance will be created.
|
*/
|
|
onClassExtended: function(cls, data, hooks) {
|
var onBeforeClassCreated = hooks.onBeforeCreated;
|
|
hooks.onBeforeCreated = function(cls, data) {
|
var Controller = Ext.app.Controller,
|
ctrlRegex = Controller.controllerRegex,
|
requires = [],
|
className, namespace, requires, proto, match;
|
|
proto = cls.prototype;
|
|
/*
|
* Namespace resolution is tricky business: we should know what namespace
|
* this Controller descendant belongs to, or model/store/view dependency
|
* resolution will be either ambiguous or plainly not possible. To avoid
|
* guessing games we try to look for a forward hint ($namespace) that
|
* Application class sets when its onClassExtended gets processed; if that
|
* fails we try to deduce namespace from class name.
|
*
|
* Note that for Ext.app.Application, Controller.onClassExtended gets executed
|
* *before* Application.onClassExtended so we have to delay namespace handling
|
* until after Application.onClassExtended kicks in, hence it is done in this hook.
|
*/
|
className = Ext.getClassName(cls);
|
namespace = data.$namespace ||
|
Ext.app.getNamespace(className) ||
|
((match = ctrlRegex.exec(className)) && match[1]);
|
|
if (namespace) {
|
proto.$namespace = namespace;
|
}
|
//<debug>
|
else {
|
Ext.log.warn("Missing namespace for " + className + ", please define it "+
|
"in namespaces property of your Application class.");
|
}
|
//</debug>
|
|
Controller.processDependencies(proto, requires, namespace, 'model', data.models);
|
Controller.processDependencies(proto, requires, namespace, 'view', data.views);
|
Controller.processDependencies(proto, requires, namespace, 'store', data.stores);
|
Controller.processDependencies(proto, requires, namespace, 'controller', data.controllers);
|
|
Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this));
|
};
|
},
|
|
<span id='Ext-app-Controller-method-constructor'> /**
|
</span> * Creates new Controller.
|
*
|
* @param {Object} [config] Configuration object.
|
*/
|
constructor: function (config) {
|
var me = this;
|
|
me.mixins.observable.constructor.call(me, config);
|
|
if (me.refs) {
|
me.ref(me.refs);
|
}
|
|
me.eventbus = Ext.app.EventBus;
|
|
me.initAutoGetters();
|
},
|
|
<span id='Ext-app-Controller-method-initAutoGetters'> initAutoGetters: function() {
|
</span> var proto = this.self.prototype,
|
prop, fn;
|
|
for (prop in proto) {
|
fn = proto[prop];
|
|
// Look for the marker placed on the getters by processDependencies so that
|
// we can know what to call cheaply:
|
if (fn && fn['Ext.app.getter']) {
|
fn.call(this);
|
}
|
}
|
},
|
|
<span id='Ext-app-Controller-method-doInit'> doInit: function(app) {
|
</span> var me = this;
|
|
if (!me._initialized) {
|
me.init(app);
|
me._initialized = true;
|
}
|
},
|
|
<span id='Ext-app-Controller-method-finishInit'> finishInit: function(app) {
|
</span> var me = this,
|
controllers = me.controllers,
|
controller, i, l;
|
|
if (me._initialized && controllers && controllers.length) {
|
for (i = 0, l = controllers.length; i < l; i++) {
|
controller = me.getController(controllers[i]);
|
controller.finishInit(app);
|
}
|
}
|
},
|
|
<span id='Ext-app-Controller-method-init'> /**
|
</span> * A template method that is called when your application boots. It is called before the
|
* {@link Ext.app.Application Application}'s launch function is executed so gives a hook point
|
* to run any code before your Viewport is created.
|
*
|
* @param {Ext.app.Application} application
|
*
|
* @template
|
*/
|
init: Ext.emptyFn,
|
|
<span id='Ext-app-Controller-method-onLaunch'> /**
|
</span> * A template method like {@link #init}, but called after the viewport is created.
|
* This is called after the {@link Ext.app.Application#launch launch} method of Application
|
* is executed.
|
*
|
* @param {Ext.app.Application} application
|
*
|
* @template
|
*/
|
onLaunch: Ext.emptyFn,
|
|
<span id='Ext-app-Controller-method-ref'> ref: function(refs) {
|
</span> var me = this,
|
i = 0,
|
length = refs.length,
|
info, ref, fn;
|
|
refs = Ext.Array.from(refs);
|
|
me.references = me.references || [];
|
|
for (; i < length; i++) {
|
info = refs[i];
|
ref = info.ref;
|
fn = 'get' + Ext.String.capitalize(ref);
|
|
if (!me[fn]) {
|
me[fn] = Ext.Function.pass(me.getRef, [ref, info], me);
|
}
|
me.references.push(ref.toLowerCase());
|
}
|
},
|
|
<span id='Ext-app-Controller-method-addRef'> /**
|
</span> * Registers one or more {@link #refs references}.
|
*
|
* @param {Object/Object[]} refs
|
*/
|
addRef: function(refs) {
|
this.ref(refs);
|
},
|
|
<span id='Ext-app-Controller-method-getRef'> getRef: function(ref, info, config) {
|
</span> var me = this,
|
refCache = me.refCache || (me.refCache = {}),
|
cached = refCache[ref];
|
|
info = info || {};
|
config = config || {};
|
|
Ext.apply(info, config);
|
|
if (info.forceCreate) {
|
return Ext.ComponentManager.create(info, 'component');
|
}
|
|
if (!cached) {
|
if (info.selector) {
|
refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0];
|
}
|
|
if (!cached && info.autoCreate) {
|
refCache[ref] = cached = Ext.ComponentManager.create(info, 'component');
|
}
|
|
if (cached) {
|
cached.on('beforedestroy', function() {
|
refCache[ref] = null;
|
});
|
}
|
}
|
|
return cached;
|
},
|
|
<span id='Ext-app-Controller-method-hasRef'> /**
|
</span> * Returns `true` if a {@link #refs reference} is registered.
|
*
|
* @return {Boolean}
|
*/
|
hasRef: function(ref) {
|
var references = this.references;
|
return references && Ext.Array.indexOf(references, ref.toLowerCase()) !== -1;
|
},
|
|
<span id='Ext-app-Controller-method-control'> /**
|
</span> * Adds listeners to components selected via {@link Ext.ComponentQuery}. Accepts an
|
* object containing component paths mapped to a hash of listener functions.
|
*
|
* In the following example the `updateUser` function is mapped to to the `click`
|
* event on a button component, which is a child of the `useredit` component.
|
*
|
* Ext.define('AM.controller.Users', {
|
* init: function() {
|
* this.control({
|
* 'useredit button[action=save]': {
|
* click: this.updateUser
|
* }
|
* });
|
* },
|
*
|
* updateUser: function(button) {
|
* console.log('clicked the Save button');
|
* }
|
* });
|
*
|
* Or alternatively one call `control` with two arguments:
|
*
|
* this.control('useredit button[action=save]', {
|
* click: this.updateUser
|
* });
|
*
|
* See {@link Ext.ComponentQuery} for more information on component selectors.
|
*
|
* @param {String/Object} selectors If a String, the second argument is used as the
|
* listeners, otherwise an object of selectors -> listeners is assumed
|
* @param {Object} [listeners] Config for listeners.
|
*/
|
control: function(selectors, listeners, controller) {
|
var me = this,
|
ctrl = controller,
|
obj;
|
|
if (Ext.isString(selectors)) {
|
obj = {};
|
obj[selectors] = listeners;
|
}
|
else {
|
obj = selectors;
|
ctrl = listeners;
|
}
|
|
me.eventbus.control(obj, ctrl || me);
|
},
|
|
<span id='Ext-app-Controller-method-listen'> /**
|
</span> * Adds listeners to different event sources (also called "event domains"). The
|
* primary event domain is that of components, but there are also other event domains:
|
* {@link Ext.app.domain.Global Global} domain that intercepts events fired from
|
* {@link Ext#globalEvents} Observable instance, {@link Ext.app.domain.Controller Controller}
|
* domain can be used to listen to events fired by other Controllers,
|
* {@link Ext.app.domain.Store Store} domain gives access to Store events, and
|
* {@link Ext.app.domain.Direct Direct} domain can be used with Ext.Direct Providers
|
* to listen to their events.
|
*
|
* To listen to "bar" events fired by a controller with id="foo":
|
*
|
* Ext.define('AM.controller.Users', {
|
* init: function() {
|
* this.listen({
|
* controller: {
|
* '#foo': {
|
* bar: this.onFooBar
|
* }
|
* }
|
* });
|
* },
|
* ...
|
* });
|
*
|
* To listen to "bar" events fired by any controller, and "baz" events
|
* fired by Store with storeId="baz":
|
*
|
* Ext.define('AM.controller.Users', {
|
* init: function() {
|
* this.listen({
|
* controller: {
|
* '*': {
|
* bar: this.onAnyControllerBar
|
* }
|
* },
|
* store: {
|
* '#baz': {
|
* baz: this.onStoreBaz
|
* }
|
* }
|
* });
|
* },
|
* ...
|
* });
|
*
|
* To listen to "idle" events fired by {@link Ext#globalEvents} when other event
|
* processing is complete and Ext JS is about to return control to the browser:
|
*
|
* Ext.define('AM.controller.Users', {
|
* init: function() {
|
* this.listen({
|
* global: { // Global events are always fired
|
* idle: this.onIdle // from the same object, so there
|
* } // are no selectors
|
* });
|
* }
|
* });
|
*
|
* As this relates to components, the following example:
|
*
|
* Ext.define('AM.controller.Users', {
|
* init: function() {
|
* this.listen({
|
* component: {
|
* 'useredit button[action=save]': {
|
* click: this.updateUser
|
* }
|
* }
|
* });
|
* },
|
* ...
|
* });
|
*
|
* Is equivalent to:
|
*
|
* Ext.define('AM.controller.Users', {
|
* init: function() {
|
* this.control({
|
* 'useredit button[action=save]': {
|
* click: this.updateUser
|
* }
|
* });
|
* },
|
* ...
|
* });
|
*
|
* Of course, these can all be combined in a single call and used instead of
|
* `control`, like so:
|
*
|
* Ext.define('AM.controller.Users', {
|
* init: function() {
|
* this.listen({
|
* global: {
|
* idle: this.onIdle
|
* },
|
* controller: {
|
* '*': {
|
* foobar: this.onAnyFooBar
|
* },
|
* '#foo': {
|
* bar: this.onFooBar
|
* }
|
* },
|
* component: {
|
* 'useredit button[action=save]': {
|
* click: this.updateUser
|
* }
|
* },
|
* store: {
|
* '#qux': {
|
* load: this.onQuxLoad
|
* }
|
* }
|
* });
|
* },
|
* ...
|
* });
|
*
|
* @param {Object} to Config object containing domains, selectors and listeners.
|
*/
|
listen: function (to, controller) {
|
this.eventbus.listen(to, controller || this);
|
},
|
|
<span id='Ext-app-Controller-method-getController'> /**
|
</span> * Returns instance of a {@link Ext.app.Controller Controller} with the given id.
|
* When controller doesn't exist yet, it's created. Note that this method depends
|
* on Application instance and will return undefined when Application is not
|
* accessible. The only exception is when this Controller instance's id is requested;
|
* in that case we always return the instance even if Application is no available.
|
*
|
* @param {String} id
|
*
|
* @return {Ext.app.Controller} controller instance or undefined.
|
*/
|
getController: function(id) {
|
var me = this,
|
app = me.application;
|
|
if (id === me.id) {
|
return me;
|
}
|
|
return app && app.getController(id);
|
},
|
|
<span id='Ext-app-Controller-method-getStore'> /**
|
</span> * Returns instance of a {@link Ext.data.Store Store} with the given name.
|
* When store doesn't exist yet, it's created.
|
*
|
* @param {String} name
|
*
|
* @return {Ext.data.Store} a store instance.
|
*/
|
getStore: function(name) {
|
var storeId, store;
|
|
storeId = (name.indexOf('@') == -1) ? name : name.split('@')[0];
|
store = Ext.StoreManager.get(storeId);
|
|
if (!store) {
|
name = Ext.app.Controller.getFullName(name, 'store', this.$namespace);
|
|
if (name) {
|
store = Ext.create(name.absoluteName, {
|
storeId: storeId
|
});
|
}
|
}
|
|
return store;
|
},
|
|
<span id='Ext-app-Controller-method-getModel'> /**
|
</span> * Returns a {@link Ext.data.Model Model} class with the given name.
|
* A shorthand for using {@link Ext.ModelManager#getModel}.
|
*
|
* @param {String} name
|
*
|
* @return {Ext.data.Model} a model class.
|
*/
|
getModel: function(model) {
|
var name = Ext.app.Controller.getFullName(model, 'model', this.$namespace);
|
|
return name && Ext.ModelManager.getModel(name.absoluteName);
|
},
|
|
<span id='Ext-app-Controller-method-getView'> /**
|
</span> * Returns a View class with the given name. To create an instance of the view,
|
* you can use it like it's used by Application to create the Viewport:
|
*
|
* this.getView('Viewport').create();
|
*
|
* @param {String} name
|
*
|
* @return {Ext.Base} a view class.
|
*/
|
getView: function(view) {
|
var name = Ext.app.Controller.getFullName(view, 'view', this.$namespace);
|
|
return name && Ext.ClassManager.get(name.absoluteName);
|
},
|
|
<span id='Ext-app-Controller-method-getApplication'> /**
|
</span> * Returns the base {@link Ext.app.Application} for this controller.
|
*
|
* @return {Ext.app.Application} the application
|
*/
|
getApplication: function() {
|
return this.application;
|
}
|
});
|
</pre>
|
</body>
|
</html>
|