icloudtweetdeckhipchattelegramhangoutsslackgmailskypefacebook-workplaceoutlookemailmicrosoft-teamsdiscordmessengercustom-servicesmacoslinuxwindowsinboxwhatsapp
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
278 lines
10 KiB
278 lines
10 KiB
9 years ago
|
/**
|
||
|
* A Profile represents a range of devices that fall under a common category. For the vast majority of apps that use
|
||
|
* device profiles, the app defines a Phone profile and a Tablet profile. Doing this enables you to easily customize
|
||
|
* the experience for the different sized screens offered by those device types.
|
||
|
*
|
||
|
* Only one Profile can be active at a time, and each Profile defines a simple {@link #isActive} function that should
|
||
|
* return either true or false. The first Profile to return true from its isActive function is set as your Application's
|
||
|
* {@link Ext.app.Application#currentProfile current profile}.
|
||
|
*
|
||
|
* A Profile can define any number of {@link #models}, {@link #views}, {@link #controllers} and {@link #stores} which
|
||
|
* will be loaded if the Profile is activated. It can also define a {@link #launch} function that will be called after
|
||
|
* all of its dependencies have been loaded, just before the {@link Ext.app.Application#launch application launch}
|
||
|
* function is called.
|
||
|
*
|
||
|
* ## Sample Usage
|
||
|
*
|
||
|
* First you need to tell your Application about your Profile(s):
|
||
|
*
|
||
|
* Ext.application({
|
||
|
* name: 'MyApp',
|
||
|
* profiles: ['Phone', 'Tablet']
|
||
|
* });
|
||
|
*
|
||
|
* This will load app/profile/Phone.js and app/profile/Tablet.js. Here's how we might define the Phone profile:
|
||
|
*
|
||
|
* Ext.define('MyApp.profile.Phone', {
|
||
|
* extend: 'Ext.app.Profile',
|
||
|
*
|
||
|
* views: ['Main'],
|
||
|
*
|
||
|
* isActive: function() {
|
||
|
* return Ext.os.is('Phone');
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* The isActive function returns true if we detect that we are running on a phone device. If that is the case the
|
||
|
* Application will set this Profile active and load the 'Main' view specified in the Profile's {@link #views} config.
|
||
|
*
|
||
|
* ## Class Specializations
|
||
|
*
|
||
|
* Because Profiles are specializations of an application, all of the models, views, controllers and stores defined
|
||
|
* in a Profile are expected to be namespaced under the name of the Profile. Here's an expanded form of the example
|
||
|
* above:
|
||
|
*
|
||
|
* Ext.define('MyApp.profile.Phone', {
|
||
|
* extend: 'Ext.app.Profile',
|
||
|
*
|
||
|
* views: ['Main'],
|
||
|
* controllers: ['Signup'],
|
||
|
* models: ['MyApp.model.Group'],
|
||
|
*
|
||
|
* isActive: function() {
|
||
|
* return Ext.os.is('Phone');
|
||
|
* }
|
||
|
* });
|
||
|
*
|
||
|
* In this case, the Profile is going to load *app/view/phone/Main.js*, *app/controller/phone/Signup.js* and
|
||
|
* *app/model/Group.js*. Notice that in each of the first two cases the name of the profile ('phone' in this case) was
|
||
|
* injected into the class names. In the third case we specified the full Model name (for Group) so the Profile name
|
||
|
* was not injected.
|
||
|
*
|
||
|
* For a fuller understanding of the ideas behind Profiles and how best to use them in your app, we suggest you read
|
||
|
* the [device profiles guide](/touch/2.4/core_concepts/device_profiles.html).
|
||
|
*
|
||
|
*/
|
||
|
Ext.define('Ext.app.Profile', {
|
||
|
mixins: {
|
||
|
observable: "Ext.mixin.Observable"
|
||
|
},
|
||
|
|
||
|
config: {
|
||
|
/**
|
||
|
* @cfg {String} namespace The namespace that this Profile's classes can be found in. Defaults to the lowercased
|
||
|
* Profile {@link #name}, for example a Profile called MyApp.profile.Phone will by default have a 'phone'
|
||
|
* namespace, which means that this Profile's additional models, stores, views and controllers will be loaded
|
||
|
* from the MyApp.model.phone.*, MyApp.store.phone.*, MyApp.view.phone.* and MyApp.controller.phone.* namespaces
|
||
|
* respectively.
|
||
|
* @accessor
|
||
|
*/
|
||
|
namespace: 'auto',
|
||
|
|
||
|
/**
|
||
|
* @cfg {String} name The name of this Profile. Defaults to the last section of the class name (e.g. a profile
|
||
|
* called MyApp.profile.Phone will default the name to 'Phone').
|
||
|
* @accessor
|
||
|
*/
|
||
|
name: 'auto',
|
||
|
|
||
|
/**
|
||
|
* @cfg {String} mainView
|
||
|
*/
|
||
|
mainView: {
|
||
|
$value: null,
|
||
|
lazy: true
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @cfg {Ext.app.Application} application The {@link Ext.app.Application Application} instance that this
|
||
|
* Profile is bound to. This is set automatically.
|
||
|
* @accessor
|
||
|
* @readonly
|
||
|
*/
|
||
|
application: null,
|
||
|
|
||
|
// @cmd-auto-dependency {aliasPrefix: "controller.", profile: true, blame: "all"}
|
||
|
/**
|
||
|
* @cfg {Array} controllers Any additional {@link Ext.app.Controller Controllers} to load for this
|
||
|
* profile. Note that each item here will be prepended with the Profile namespace when loaded. Example usage:
|
||
|
*
|
||
|
* controllers: [
|
||
|
* 'Users',
|
||
|
* 'MyApp.controller.Products'
|
||
|
* ]
|
||
|
*
|
||
|
* This will load *MyApp.controller.tablet.Users* and *MyApp.controller.Products*.
|
||
|
* @accessor
|
||
|
*/
|
||
|
controllers: [],
|
||
|
|
||
|
// @cmd-auto-dependency {aliasPrefix : "model.", profile: true, blame: "all"}
|
||
|
/**
|
||
|
* @cfg {Array} models Any additional {@link Ext.app.Application#models Models} to load for this profile. Note
|
||
|
* that each item here will be prepended with the Profile namespace when loaded. Example usage:
|
||
|
*
|
||
|
* models: [
|
||
|
* 'Group',
|
||
|
* 'MyApp.model.User'
|
||
|
* ]
|
||
|
*
|
||
|
* This will load *MyApp.model.tablet.Group* and *MyApp.model.User*.
|
||
|
* @accessor
|
||
|
*/
|
||
|
models: [],
|
||
|
|
||
|
// @cmd-auto-dependency {aliasPrefix: "view.", profile: true, blame: "all"}
|
||
|
/**
|
||
|
* @cfg {Array} views Any additional {@link Ext.app.Application#views views} to load for this profile. Note
|
||
|
* that each item here will be prepended with the Profile namespace when loaded. Example usage:
|
||
|
*
|
||
|
* views: [
|
||
|
* 'Main',
|
||
|
* 'MyApp.view.Login'
|
||
|
* ]
|
||
|
*
|
||
|
* This will load *MyApp.view.tablet.Main* and *MyApp.view.Login*.
|
||
|
* @accessor
|
||
|
*/
|
||
|
views: [],
|
||
|
|
||
|
// @cmd-auto-dependency {aliasPrefix: "store.", profile: true, blame: "all"}
|
||
|
/**
|
||
|
* @cfg {Array} stores Any additional {@link Ext.app.Application#stores Stores} to load for this profile. Note
|
||
|
* that each item here will be prepended with the Profile namespace when loaded. Example usage:
|
||
|
*
|
||
|
* stores: [
|
||
|
* 'Users',
|
||
|
* 'MyApp.store.Products'
|
||
|
* ]
|
||
|
*
|
||
|
* This will load *MyApp.store.tablet.Users* and *MyApp.store.Products*.
|
||
|
* @accessor
|
||
|
*/
|
||
|
stores: []
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Creates a new Profile instance
|
||
|
*/
|
||
|
constructor: function(config) {
|
||
|
this.initConfig(config);
|
||
|
|
||
|
this.mixins.observable.constructor.apply(this, arguments);
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* Determines whether or not this Profile is active on the device isActive is executed on. Should return true if
|
||
|
* this profile is meant to be active on this device, false otherwise. Each Profile should implement this function
|
||
|
* (the default implementation just returns false).
|
||
|
* @return {Boolean} True if this Profile should be activated on the device it is running on, false otherwise
|
||
|
*/
|
||
|
isActive: function() {
|
||
|
return false;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @method
|
||
|
* The launch function is called by the {@link Ext.app.Application Application} if this Profile's {@link #isActive}
|
||
|
* function returned true. This is typically the best place to run any profile-specific app launch code. Example
|
||
|
* usage:
|
||
|
*
|
||
|
* launch: function() {
|
||
|
* Ext.create('MyApp.view.tablet.Main');
|
||
|
* }
|
||
|
*/
|
||
|
launch: Ext.emptyFn,
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
applyNamespace: function(name) {
|
||
|
if (name == 'auto') {
|
||
|
name = this.getName();
|
||
|
}
|
||
|
|
||
|
return name.toLowerCase();
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
*/
|
||
|
applyName: function(name) {
|
||
|
if (name == 'auto') {
|
||
|
var pieces = this.$className.split('.');
|
||
|
name = pieces[pieces.length - 1];
|
||
|
}
|
||
|
|
||
|
return name;
|
||
|
},
|
||
|
onClassExtended: function(cls, data, hooks) {
|
||
|
var onBeforeClassCreated = hooks.onBeforeCreated;
|
||
|
|
||
|
hooks.onBeforeCreated = function(cls, data) {
|
||
|
var Controller = Ext.app.Controller,
|
||
|
requires = [],
|
||
|
proto = cls.prototype,
|
||
|
namespace;
|
||
|
|
||
|
namespace = Controller.resolveNamespace(cls, data);
|
||
|
|
||
|
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));
|
||
|
};
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @private
|
||
|
* Computes the full class names of any specified model, view, controller and store dependencies, returns them in
|
||
|
* an object map for easy loading
|
||
|
*/
|
||
|
getDependencies: function() {
|
||
|
var allClasses = [],
|
||
|
appName = this.getApplication().getName(),
|
||
|
namespace = this.getNamespace(),
|
||
|
map = {
|
||
|
model: this.getModels(),
|
||
|
view: this.getViews(),
|
||
|
controller: this.getControllers(),
|
||
|
store: this.getStores()
|
||
|
},
|
||
|
classType, classNames;
|
||
|
|
||
|
for (classType in map) {
|
||
|
classNames = [];
|
||
|
|
||
|
Ext.each(map[classType], function(className) {
|
||
|
if (Ext.isString(className)) {
|
||
|
//we check name === appName to allow MyApp.profile.MyApp to exist
|
||
|
if (Ext.isString(className) && (Ext.ClassManager.getPrefix(className) === "" || className === appName)) {
|
||
|
className = appName + '.' + classType + '.' + namespace + '.' + className;
|
||
|
}
|
||
|
|
||
|
classNames.push(className);
|
||
|
allClasses.push(className);
|
||
|
}
|
||
|
}, this);
|
||
|
|
||
|
map[classType] = classNames;
|
||
|
}
|
||
|
|
||
|
map.all = allClasses;
|
||
|
|
||
|
return map;
|
||
|
}
|
||
|
});
|