Many classes have shortcut names used when creating (instantiating) a class with a
configuration object. The shortcut name is referred to as an alias
(or xtype
if the
class extends Ext.Component). The alias/xtype is listed next to the class name of
applicable classes for quick reference.
Framework classes or their members may be specified as private
or protected
. Else,
the class / member is public
. Public
, protected
, and private
are access
descriptors used to convey how and when the class or class member should be used.
Public classes and class members are available for use by any other class or application code and may be relied upon as a stable and persistent within major product versions. Public classes and members may safely be extended via a subclass.
Protected class members are stable public
members intended to be used by the
owning class or its subclasses. Protected members may safely be extended via a subclass.
Private classes and class members are used internally by the framework and are not intended to be used by application developers. Private classes and members may change or be omitted from the framework at any time without notice and should not be relied upon in application logic.
static
label next to the
method name. *See Static below.Below is an example class member that we can disect to show the syntax of a class member (the lookupComponent method as viewed from the Ext.button.Button class in this case).
Let's look at each part of the member row:
lookupComponent
in this example)( item )
in this example)Ext.Component
in this case). This may be omitted for methods that do not
return anything other than undefined
or may display as multiple possible values
separated by a forward slash /
signifying that what is returned may depend on the
results of the method call (i.e. a method may return a Component if a get method calls is
successful or false
if unsuccessful which would be displayed as
Ext.Component/Boolean
).PROTECTED
in
this example - see the Flags section below)Ext.container.Container
in this example). The source
class will be displayed as a blue link if the member originates from the current class
and gray if it is inherited from an ancestor or mixed-in class.view source
in the example)item : Object
in the example).undefined
a "Returns" section
will note the type of class or object returned and a description (Ext.Component
in the
example)Available since 3.4.0
- not pictured in
the example) just after the member descriptionDefaults to: false
)The API documentation uses a number of flags to further commnicate the class member's function and intent. The label may be represented by a text label, an abbreviation, or an icon.
classInstance.method1().method2().etc();
false
is returned from
an event handler- Indicates a framework class
- A singleton framework class. *See the singleton flag for more information
- A component-type framework class (any class within the Ext JS framework that extends Ext.Component)
- Indicates that the class, member, or guide is new in the currently viewed version
- Indicates a class member of type config
- Indicates a class member of type property
- Indicates a class member of type
method
- Indicates a class member of type event
- Indicates a class member of type
theme variable
- Indicates a class member of type
theme mixin
- Indicates that the class, member, or guide is new in the currently viewed version
Just below the class name on an API doc page is a row of buttons corresponding to the types of members owned by the current class. Each button shows a count of members by type (this count is updated as filters are applied). Clicking the button will navigate you to that member section. Hovering over the member-type button will reveal a popup menu of all members of that type for quick navigation.
Getting and setter methods that correlate to a class config option will show up in the methods section as well as in the configs section of both the API doc and the member-type menus just beneath the config they work with. The getter and setter method documentation will be found in the config row for easy reference.
Your page history is kept in localstorage and displayed (using the available real estate) just below the top title bar. By default, the only search results shown are the pages matching the product / version you're currently viewing. You can expand what is displayed by clicking on the button on the right-hand side of the history bar and choosing the "All" radio option. This will show all recent pages in the history bar for all products / versions.
Within the history config menu you will also see a listing of your recent page visits. The results are filtered by the "Current Product / Version" and "All" radio options. Clicking on the button will clear the history bar as well as the history kept in local storage.
If "All" is selected in the history config menu the checkbox option for "Show product details in the history bar" will be enabled. When checked, the product/version for each historic page will show alongside the page name in the history bar. Hovering the cursor over the page names in the history bar will also show the product/version as a tooltip.
Both API docs and guides can be searched for using the search field at the top of the page.
On API doc pages there is also a filter input field that filters the member rows using the filter string. In addition to filtering by string you can filter the class members by access level, inheritance, and read only. This is done using the checkboxes at the top of the page.
The checkbox at the bottom of the API class navigation tree filters the class list to include or exclude private classes.
Clicking on an empty search field will show your last 10 searches for quick navigation.
Each API doc page (with the exception of Javascript primitives pages) has a menu view of metadata relating to that class. This metadata view will have one or more of the following:
Ext.button.Button
class has an alternate class name of Ext.Button
). Alternate class
names are commonly maintained for backward compatibility.Runnable examples (Fiddles) are expanded on a page by default. You can collapse and expand example code blocks individually using the arrow on the top-left of the code block. You can also toggle the collapse state of all examples using the toggle button on the top-right of the page. The toggle-all state will be remembered between page loads.
Class members are collapsed on a page by default. You can expand and collapse members using the arrow icon on the left of the member row or globally using the expand / collapse all toggle button top-right.
Viewing the docs on narrower screens or browsers will result in a view optimized for a smaller form factor. The primary differences between the desktop and "mobile" view are:
The class source can be viewed by clicking on the class name at the top of an API doc page. The source for class members can be viewed by clicking on the "view source" link on the right-hand side of the member row.
"Microloader" is the name for Sencha's data-driven, dynamic loader for JavaScript and CSS. The Microloader is provided by Sencha Cmd as part of your generated application. This guide will give you a solid understanding of what the Microloader does and how you can tune it for your specific requirements.
It is important to clarify that the Microloader used by Ext 6 is currently a different
implementation than that used by Ext JS 5 or by Sencha Touch. The Ext JS 6 Microloader
provides all of the same functionality as was provided by the Sencha Touch microloader,
but has some improvements and new controls available in the "app.json"
file, which are
discussed further later in this document. All microloader implementations are provided by
Sencha Cmd, and upgrades to the microloader will be applied by the "sencha app upgrade"
process.
This file is where you specify details about your application. This configuration file is
first consumed by the Sencha Cmd build process. Sencha Cmd transforms the content of
"app.json"
and passes on the resulting manifest to the Microloader to use at runtime. Lastly,
Ext JS itself also consults the runtime manifest for configuration options.
When you launch your application, you will find the processed content of "app.json"
loaded
as “Ext.manifest”. Ext JS 6 uses the Ext.manifest properties that you have specified to do
things like enable the Compatibility Layer. There are various options supported by the
Microloader for getting this object loaded which we'll discuss later.
To use the Microloader, your page will need to contain the following script tag:
<script id="microloader" data-app="12345" type="text/javascript" src="bootstrap.js"></script>
By default, this script tag will be replaced by the build process but is used during development to load the application. The data-app attribute should have been generated for you during app scaffold. This is a unique ID used in local storage to prevent data collision.
The "app.json"
file generated by Sencha Cmd contains many properties that you may want to
adjust. These properties are documented inline to explain what they each control.
If you are upgrading a project, your "app.json"
may not contain all of the possible
options. After performing the upgrade, the default values for any missing properties can
instead be found in “.sencha/app/app.defaults.json”.
The following are the properties most often of interest.
This is the path to the application's HTML document (relative to the "app.json"
file). By
default this property is set to "index.html". If you server uses PHP, ASP, JSP or other
technology, you can change this value to point at the proper file like so:
"indexHtmlPath": "../page.jsp"
If you change this setting, you will likely also need to change your "output" options (see below).
The name of the framework; either "ext" or "touch". For example:
"framework": "ext"
For Ext JS applications, this is the name of the theme package. For example:
"theme": "ext-theme-crisp"
For Ext JS 6 applications, this is the name of the toolkit package. For example:
"toolkit": "classic"
An array of descriptions of JavaScript code files to load. By default, an Ext JS 6 application will have something like this:
"js": [{
"path": "app.js",
"bundle": true
}]
This entry specifies your application's entry point. The "bundle" flag indicates that when you run "sencha app build", this entry should be replaced by the concatenated output of the build. You can add other files to this array like so:
"js": [{
"path": "library.js",
"includeInBundle": true
},{
"path": "app.js",
"bundle": true
}]
When you add extra files, there are some optional properties that indicate how the build process will treat them. For example, in the above case, "library.js" will be included in the concatenated build output and removed from the runtime manifest.
If instead you removed "includeInBundle", then "library.js" would be assumed to reside in your app folder and would then be copied to the build output folder. The entry would remain in the manifest and be loaded separately by the Microloader.
To simply pass along the entry for the Microloader to load (and not be copied by the build process), add the "remote" property like so:
"js": [{
"path": "library.js",
"remote": true
},{
"path": "app.js",
"bundle": true
}]
While you can add entries to this array, most dependencies will appear in "requires"
statements in your code or in "app.json"
(to require packages).
Note: For Sencha Touch, you will typically have "sencha-touch-debug.js" in the "js" array. This entry is not needed for Ext JS 6 because the "framework" setting is sufficient.
Your CSS assets are handled slightly different than JavaScript. This is because in a
stock Sencha Cmd application, CSS is compiled from the .scss
source. The initial
content of the "css" property looks something like this:
"css": [{
"path": "boostrap.css",
"bootstrap": true
}],
This CSS file is a simple stub that imports a build of your "sass"
folder. The "bootstrap"
flag indicates that the entry is used for development but should be removed from build
output. For a build, the compiled CSS file will be appended to the "css" array of the
generated manifest.
Initially, "bootstrap.css" imports the theme from the framework and looks something like this:
@import "..../ext-theme-neptune/build/ext-theme-neptune-all.css";
As you build your app, this file is updated to point at the most recently built CSS file. For example if you run "sencha app build", the production CSS file will be imported by "bootstrap.css" like so:
@import "..../build/..../app-all.css";
The "css" entries also support the "remote" property. When remote is not set they operate in the same way as "js" entries in that they are copied to the build output folder.
As Javascript has evolved over the years, different releases of ECMA Script have introduced new features and capabilities. With so many different release levels, Sencha Cmd can be configured with the input ES level of your application source code. This sets the correct level for parsing your source and is used to determine if transpiling the output is required.
By default, Sencha Cmd sets the input language to ESNext (the latest ES level that the Google Closure Compiler supports) and the build output will be transpiled down to ES5. These values can be configured as required.
The "language" configuration is used to change these default values and is placed in 'app.json' (or 'package.json' as appropriate) or in 'workspace.json' to serve as defaults for apps and packages.
For example, if the input level is set to ES7 and the output level is set to ES5, Sencha Cmd will parse the input against ES7 syntax, rejecting any higher level syntax encountered. It will then transpile the build output to ES5. Transpiling your input source is useful when you wish to develop at a later level of ECMA Script but yet wish to have your build capable of running on systems which may not support such ES levels.
Sencha Cmd recognizes the following ES levels for input and output:
"input": `ES5`, `ES6`, `ES7`, `ES8`, and `NEXT`
"output": `ES5`, `ES6`, `ES7`, `ES8`, `NEXT` and `ANY`
NOTE: Even though the input values only go to ES8 for specific levels, the current version of the closure compiler shipped with Cmd 7.8.0 can parse up to ES11.
The 'ANY' output indicates you do NOT wish to have the input source transpiled and it should be compressed only.
Some common use cases are as follows.
While this is the default language cofiguration, and is not specified in the generated app.json, the following is the explicit equivalent to show you how this would manually be configured:
"language": {
"js": {
"input": "NEXT", // Input ES level is closure compiler's highest supported level
"output": "ES5" // Transpile input source to ES5
}
},
The following will reject all ES6+ syntax (only permit ES5) and, as the default output is ES5, no transpilation will take place.
"language": {
"js": {
"input": "ES5" // Parse source against ES5, rejecting any higher level source
}
},
If your target environment supports up to ES6 natively, the transpiler can and should be disabled for size and performance benefits. The following will accept ES6 (and lower) syntax for input. As input and output levels are the same, no transpilation will happen.
"language": {
"js": {
"input": "ES6", // Input level is ES6
"output": "ES6" // As input and output levels match, no transpilation will occur
}
},
If your wish to code using the latest ES syntax, however your target system only supports ES7, this can be done by configuring the output level to ES7. The input will be parsed against NEXT syntax and output transpiled down to ES7 if any ES8 or higher syntax is encountered.
"language": {
"js": {
"output": "ES7" // Transpile ES8+ syntax down to ES7
}
},
If your target environment supports ES6 and beyond natively, the transpiler can and should be disabled for size and performance benefits. The following will accept syntax and disable the transpiler.
"language": {
"js": {
"output": "ANY"
}
},
This array holds names of required packages. When Sencha Cmd processes this list, it will
automatically download and extract any missing packages into your workspace. Packages can
likewise contain requires
in their "package.json"
. These will also be downloaded and
extracted as needed.
These package names can also contain version requirements. For details on specifying version numbers, see Sencha Cmd Packages.
The "output" object gives you the ability to control where and how build outputs are
generated. This object can control many aspects of the build output. In our use of
indexHtmlPath
above, we told Sencha Cmd that the source for the page was "../page.jsp"
.
To complete this process, we use output
to tell Sencha Cmd where the built page will
reside relative to the built JavaScript and CSS. To maintain the same relative arrangement
as in the source tree, we would add this to "app.json"
:
"output": {
"page": {
"path": "../page.jsp",
"enable": false
},
appCache: {
"enable": false
},
"manifest": {
"name": "bootstrap.js"
}
}
In this case, we've also added "enable" and set it to false. This combination tells Sencha Cmd were the final page will be but also not to generate it by copying the source (as specified by "indexHtmlPage").
Since we are not generating the page, the Microloader script tag will contain the same "src" value of "bootstrap.js". The "manifest" option above instructs Sencha Cmd to generate the built Microloader using the same name. This is a common need for server-side template environments like JSP or ASP, but also others.
The Application cache is a manifest used to determine what assets the browser should store for
offline access. To enable this simply toggle the enable
flag for the appCache
property
inside your output object. For example:
"output": {
"page": "index.html",
"appCache": {
"enable": true
}
}
The appCache
property seen here is used to determine if the build process will generate
an Application Cache Manifest file. If this is set to true the manifest will be generated
from the top level appCache
config object in your app.json. It will look something like this:
"appCache": {
"cache": [
"index.html"
],
"network": [
"*"
],
"fallback": []
}
The Local Storage Caching system is a seperate offline caching system from the browsers built in Application Cache. Assets are stored in Local Storage via unique keys and during bootstrap these assets will be requested first before attempting any remote loading. This allows for applications to be loaded very fast and without an internet connection. This cache also allows for delta patching of assets which means that only the changed bits of your assets, css or js, will be loaded over the network. The file will then be patched in local storage and delievered to the user.
This cache is enabled per asset via the update
propety. This can be set to either "full"
or "delta"
.
Below is an example of JS and CSS assets both with Local Storage Caching enabled.
// app.js will be delta patched on updates
"js": [
{
"path": "app.js",
"bundle": true,
"update": "delta"
}
],
// app.css will be fully downloaded on updates
"css": [
{
"path": "app.css",
"update": "full"
}
]
Once Local Storage Caching has been enabled on an asset one must globally enable the cache
config "app.json"
. Normally during development builds one will want this set to false and in production builds this would be set to true.
"cache": {
"enable": false
}
One can also configure the path and generation of deltas. When the deltas
property is set to a
truthy value all assets using Local Storage Caching will have deltas generated into the builds
"deltas"
folder. If deltas
is set to a string the value will be used as the folder name that all
patch files will be saved into. The delta toggle will have no effect if enable
is set to false.
"cache": {
"enable": true,
"deltas": true
}
Both Application Cache and Local Storage Cache will instantly load files for offline access. Because of this updated files will not be loaded into the users current application experience. Once the Microloader has detected and loaded new Application Cache or Local Storage files it will dispatch a global event allowing you to prompt the user to reload the application for the latest updates. You can listen for this event by adding the following code to your application:
Ext.application({
name: 'MyApp',
mainView: 'MyMainView',
onAppUpdate: function () {
Ext.Msg.confirm('Application Update', 'This application has an update, reload?',
function (choice) {
if (choice === 'yes') {
window.location.reload();
}
}
);
}
Many of the properties we've seen are instructions to the build process, while others are
processed by the Microloader. As mentioned, the manifest is also understood by Ext JS as
a means to configure some of its capabilities. For details on these and other properties,
review the comments in "app.json"
.
When an application has multiple variations, we can add a “builds” object to "app.json"
to
describe the desired builds like this (taken from Kitchen Sink):
"builds": {
"classic": {
"theme": "ext-theme-classic"
},
"gray": {
"theme": "ext-theme-gray"
},
"access": {
"theme": "ext-theme-access"
},
"crisp": {
"theme": "ext-theme-crisp"
},
"neptune": {
"theme": "ext-theme-neptune"
},
"neptune-touch": {
"theme": "ext-theme-neptune-touch"
}
}
Each key in “builds” is called a "build profile". The value is a set of property overrides
that are applied to the base content of "app.json"
to produce the output manifest as
described below. In this case, the “theme” property is all that is being modified for each
build profile.
In addition, there are two other optional properties that are common variations for application builds: “locales” and “themes”. These are used to automate the process of producing the final build profiles. For example, Kitchen Sink uses “locales”:
"locales": [
"en",
"he"
],
When “locales” or “themes” are given, each of the values are combined with each of the entries in “builds” to produce the final manifests. In this case “neptune-en”, "neptune-he", “crisp-en”, etc. are the final build profile names.
As mentioned previously, "app.json"
undergoes a transformation during the build process
prior to being presented at runtime as "Ext.manifest". This process consists of merging
object much like Ext.merge but with a twist: when two arrays are "merged" they
are concatenated.
The first step in this transformation is to merge settings for the desired build "environment" (for example, "production" or "testing"). Following this, if a build profile is being used, its contents are merged. Then, if either the root or build profile specified a "toolkit" ("classic" or "modern"), that object's properties are merged. Finally, if a packager ("cordova" or "phonegap") is configured, its properties are merged.
In pseudo-code this would be something like this:
var manifest = load('app.json');
// These would come from the "sencha app build" command:
var environment = 'production';
var buildProfile = 'native';
mergeConcat(manifest, manifest[environment]);
if (buildProfile) {
mergeConcat(manifest, manifest.builds[buildProfile]);
}
if (manifest.toolkit) {
mergeConcat(manifest, manifest[manifest.toolkit]);
}
if (manifest.packager) {
mergeConcat(manifest, manifest[manifest.packager]);
}
The final step in producing the manifest is to add any required packages.
When a required package specifies "js" or "css" entries in its package.json, these are concatenated in package dependency order to the front of the arrays already produced. This allows a package to handle such dependencies itself.
In addition to "js" and "css" entries, the content of each required package's package.json
file is cleaned up slightly and added to the "packages" object in the final manifest keyed
by the package name. If "app.json"
already contains a “packages” object, then that object
will be merged with the content of the corresponding package.json file. Priority is given
to "app.json"
to allow its properties to pass through as configuration options to
packages (see below).
In pseudo-code, the "app.json"
and package.json contents are merged like so:
var manifest; // from above
manifest.packages = manifest.packages || {};
var js = [], css = [];
// Expand required packages and sort in dependency order
expandAndSort(manifest.requires).forEach(function (name) {
var pkg = load('packages/' + name + '/package.json');
js = js.concat(pkg.js);
css = css.concat(pkg.css);
manifest.packages[name] = merge(pkg, manifest.packages[name]);
});
manifest.css.splice(0, 0, css);
var k = isExtJS ? 0 : manifest.js.indexOf('sencha-touch??.js');
manifest.js.splice(k, 0, js);
This produces an Ext.manifest that might look like this:
{
"name": "MyApp",
"packages": {
"ext": {
"type": "framework",
"version": "5.0.1.1255"
},
"ext-theme-neptune": {
"type": "theme",
"version": "5.0.1.1255"
},
...
},
"theme": "ext-theme-neptune",
"js": [{
"path": "app.js"
}],
"css": [{
"path": "app.css"
}],
}
The result of this merging means that package "foo" can provide some global options in its
package.json (for example, "bar") and set its default value. Any application that uses
the foo package can configure this option like so in "app.json"
:
"packages": {
"foo": {
"bar": 42
}
}
The package retrieves this value like so:
console.log('bar: ' + Ext.manifest.packages.foo.bar);
One of the major differences between loading your application in development and from a build is the order in which the individual files are presented to the browser. In previous releases, your app.js file was very nearly the first file processed by the browser. As its requirements were stated, more files were loaded and their requirements discovered and so on.
In a build, however, this order is reversed. Your app.js file will be almost always the very last file in the build output. This can easily lead to situations where code works in development but fails in production - clearly an undesirable outcome.
With Ext JS 5, the load order that will be used for the build is added to the manifest and used to load files in that same order. While this makes the manifest considerably larger, it is only used during development.
The Microloader will load your application as it is described in "app.json"
and passed along
in Ext.manifest. To do this, the Microloader must first load the manifest. There are three
basic ways to accomplish this.
For typical applications there is a single theme, locale and framework selection and that results in a single manifest. This manifest can be placed in the output markup file to optimize download time.
To enable this option, add the following to "app.json"
:
"output": {
"manifest": {
"embed": true
}
}
This setting will embed the manifest and the Microloader in the markup file.
If you use build profiles, embedding the manifest is not an option. Instead the Microloader
can request the manifest at load time given a name. By default, the generated "app.json"
file is placed in the same folder as the markup file and that is the default manifest
name. To specify a different name, you can do this:
<script type="text/javascript">
var Ext = Ext || {};
Ext.manifest = 'foo'; // loads "./foo.json" relative to your page
</script>
This approach is a useful way to manage build profiles on the server side by generating the name rather than hard-coding it.
There are times when you may want to select a build profile client-side. To simplify this, the Microloader defines a hook method called “Ext.beforeLoad”. If you define this method like the following, you can control the name or content of “Ext.manifest” prior to the Microloader processing it while leveraging its platform detection.
<script type="text/javascript">
var Ext = Ext || {};
Ext.beforeLoad = function (tags) {
var theme = location.href.match(/theme=([\w-]+)/),
locale = location.href.match(/locale=([\w-]+)/);
theme = (theme && theme[1]) || 'crisp';
locale = (locale && locale[1]) || 'en';
Ext.manifest = theme + "-" + locale;
};
</script>
The above is taken from the Ext JS 5 Kitchen Sink example. That example is built in several
themes and 2 locales (English “en” and Hebrew “he”). By providing this method the build
profile name is changed to a value like “crisp-en” which instructs the Microloader to load
the “crisp-en.json” manifest as opposed to "app.json"
.
The build profile selection process can be whatever is needed by your application. A server-side framework might chose to make this selection as the page is rendered. This could be based on cookies, or other personal data. In the above case, it is based purely on the URL.
Often the device or browser is a key selection criteria, so the Microloader passes an object called “tags” to beforeLoad. This object contains as properties the various platform tags it has detected. The set of all tags are these:
The beforeLoad method can use these tags or even modify them. This object is subsequently used to control filtering of assets (js or css items described in the manifest) as well as run-time config values set by platformConfig. This hook then allows you to control what these filters will match. Modifying the tags is, however, primarily intended for adding new tags that have meaning to your application. Custom tags should be prefixed by “ux-”. Sencha provided tags will not begin with this prefix.
The manifest also provides a "tags" property for setting the available tags. This prpoerty may be either an array of strings
"tags": ["ios", "phone", "fashion"]
or as an object literal, keyed by tag name, where the value will be the value of that tag.
"tags": {
"ios": true,
"phone": true,
"desktop": false,
"fashion": true
}
When supplied, this tags will take priority over autodetected values. Since these values are supplied by the manifest, they will not be available to the "beforeLoad" method, and will overwrite any updates to the tags made by that method in the event of a tag name collision.