Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ext.define() order

Tags:

class

extjs

I'm using Extjs5 and Sencha Cmd, and I'm working on a l10n engine (over gettext) to implement localization.

Suppose I want to offer a translation function to every class of my project, named _().

In every controller, view, model and any class, I'd like to be able to write something like that:

Ext.define('FooClass', {
  someStrings: [
    _('One string to translate'),
    _('A second string to translate'),
    _('Yet another string to translate')
  ]
});

First problem: _() must exist before all the Ext.define() of my project are executed. How to achieve that?

Second problem: _() is looking in "catalogs" that are some JavaScript files generated from .po files (gettext). So, those catalogs must have been loaded, before all the Ext.define() of my app are executed. _() is a synchronous function, it musts immediately return the translated string.

like image 643
Guid Avatar asked Sep 05 '26 00:09

Guid


2 Answers

Edit concerning the edited question

You have at least two ways to load External libraries:

Ext.Loader.loadScript

loadScript( options )

Loads the specified script URL and calls the supplied callbacks. If this method is called before Ext.isReady, the script's load will delay the transition to ready. This can be used to load arbitrary scripts that may contain further Ext.require calls.

Parameters

options : Object/String/String[] //The options object or simply the URL(s) to load.
// options params:
url : String //The URL from which to load the script.
onLoad : Function (optional) //The callback to call on successful load.
onError : Function (optional) //The callback to call on failure to load.
scope : Object (optional) //The scope (this) for the supplied callbacks.

If you still run into problems you can force the loader to do a sync loading:

syncLoadScripts: function(options) {
    var Loader = Ext.Loader,
        syncwas = Loader.syncModeEnabled;
    Loader.syncModeEnabled = true;
    Loader.loadScripts(options);
    Loader.syncModeEnabled = syncwas;
}

Place this in a file right after the ExtJS library and before the generated app.js.


Old Answer

You need to require a class when it is needed, that should solve your problems. If you don't require sencha command/the ExtJS class system cannot know that you need a specific class.

Ext.define('Class1', {
  requires: ['Class2'], 
  items: [
    {
      xtype: 'combo',
      fieldLabel: Class2.method('This is a field label')
    }
  ]
});

For further reading take a look at:

requires

requires : String[]

List of classes that have to be loaded before instantiating this class. For example:

Ext.define('Mother', {
    requires: ['Child'],
    giveBirth: function() {
        // we can be sure that child class is available.
        return new Child();
    }
});

uses

uses : String[]

List of optional classes to load together with this class. These aren't neccessarily loaded before this class is created, but are guaranteed to be available before Ext.onReady listeners are invoked. For example:

Ext.define('Mother', {
    uses: ['Child'],
    giveBirth: function() {
        // This code might, or might not work:
        // return new Child();

        // Instead use Ext.create() to load the class at the spot if not loaded already:
        return Ext.create('Child');
    }
});
like image 199
sra Avatar answered Sep 07 '26 22:09

sra


Define the translate function outside the scope of the ExtJs project and include it before the Ext application is included in the index.html. The scripts are loaded in the right order and the _() function is ready to use in your whole project.

i18n.js

function _() {
    // do the translation
}

index.html

<html>
    <head>
        <script src="i18n.js"></script>
        <script id="microloader" type="text/javascript" src="bootstrap.js"></script>
    </head>
    <body>

    </body>
</html>
like image 33
And-y Avatar answered Sep 08 '26 00:09

And-y