Tutoriel : Exemples

Exemples

Déclaration

L'ancienne méthode :

 

Si vous avez déjà utilisé une version précédente de Ext JS, vous êtes certainement familier avec Ext.extend pour créer une classe:

 

var MyWindow = Ext.extend(Object, { ... }); 

 

Cette approche est facile à utiliser pour créer une nouvelle classe qui hérite d'une autre. 


Jeton un coup d'oeil à un autre exemple :

 

My.cool.Window = Ext.extend(Ext.Window, { ... });

 

Dans cet exemple nous attribuons un espace de nom à notre nouvelle classe, qui étend Ext.Window. Il ya deux choses que nous avons besoin de noter :

  1. My.cool doit être un objet existant avant que nous puissions attribuer Window comme sa propriété
  2.  Ext.Window doit exister / chargé sur la page avant de pouvoir être référencé

Le premier point est généralement résolu avec Ext.namespace (alias de Ext.ns).  

 

Ext.ns('My.cool');
My.cool.Window = Ext.extend(Ext.Window, { ... });

 

Le deuxième point, cependant, n'est pas facile à aborder parce Ext.Window pourrait dépendre de plusieurs autres classes qui en hérite directement / indirectement , et à leur tour, ces dépendances peuvent dépendre d'autres classes. Pour cette raison, les applications écrites avant Ext JS 4 comprennent généralement toute la bibliothèque sous forme de Ext-all.js même si on a besoin que d'une toute petite partie du framework.

 La nouvelle méthode :

Ext JS 4 élimine tous ces inconvénients avec une seule méthode que vous devez retenir pour la création de la classe: Ext.define.  

 

La syntaxe de base:

 

Ext.define({String} className, {Object} members, {Function} onClassCreated);
  • className: Le nom de la classe
  • members est un objet contenant des paramettres "propriété : valeur"
  • onClassCreated est une fonction de callBack invoquée que lorsque toutes les dépendances de cette classe sont prêtes, et la classe elle-même est entièrement créé. En raison de la nature asynchrone de la création de nouvelles classes, ce rappel peut être utile dans de nombreuses situations. Ces questions seront abordées à la section IV

Exemple:


Ext.define('My.sample.Person', {
    name
: 'Unknown',

    constructor
: function(name) {
       
if (name) {
           
this.name = name;
       
}

       
return this;
   
},

    eat
: function(foodType) {
        alert
(this.name + " is eating: " + foodType);

       
return this;
   
}
});

var aaron = Ext.create('My.sample.Person');
    aaron
.eat("Salad"); // alert("Aaron is eating: Salad");

 

Note que nous avons créé une nouvelle instance de My.sample.Person l'aide de la Ext.create (). Nous aurions pu utiliser le nouveau mot-clé (nouveau My.sample.Person ()). Toutefois, il est recommandé de prendre l'habitude de toujours utiliser Ext.create car il vous permet de prendre avantage du chargement dynamique. Pour plus d'informations sur le chargement dynamique consultez le guide Mise en route


Configuration

L'ancienne méthode :

 

Avant la version 4 de ExtJs, nous n'avions pas vraiment le moyen de distinguer entre les propriétés de la classe et les configurations fournies par l'utilisateur. les propriétés de Configurations sont été définis comme propriétés de la classe normale et documentées à l'aide d'annotation @ cfg. Jetons un coup d'oeil à une classe de l'échantillon. elle est assez longue, mais elle décrit bien les problèmes dans son ensemble:


Ext.ns('My.own');
My.own.Window = Ext.extend(Object, {
   /** @readonly */
    isWindow: true,

   /** @cfg {String} title The default window's title */
    title: 'Title Here',

   /** @cfg {Object} bottomBar The default config for the bottom bar */
    bottomBar: {
        enabled: true,
        height: 50,
        resizable: false
    },

    constructor: function(config) {
        Ext.apply(this, config || {});

        this.setTitle(this.title);
        this.setBottomBar(this.bottomBar);

        return this;
    },

    setTitle: function(title) {
        // Change title only if it's a non-empty string
        if (!Ext.isString(title) || title.length === 0) {
            alert('Error: Title must be a valid non-empty string');
        }
        else {
            this.title = title;
        }

        return this;
    },

    getTitle: function() {
        return this.title;
    },

    setBottomBar: function(bottomBar) {
        // Create a new instance of My.own.WindowBottomBar if it doesn't exist
        // Change the config of the existing instance otherwise
        if (bottomBar && bottomBar.enabled) {
            if (!this.bottomBar) {
                this.bottomBar = Ext.create('My.own.WindowBottomBar', bottomBar);
            }
            else {
                this.bottomBar.setConfig(bottomBar);
            }
        }

        return this;
    },

    getBottomBar: function() {
        return this.bottomBar;
    }
});

 

En bref, My.own.Window:

  • Accepte un objet de configuration lors de l'instanciation, qui est fusionnée avec les propriétés par défaut de la classe
  • Permet à titre et à bottomBar d'être changés pendant l'exécution via setters

Cette approche a un avantage, mais en même temps est le seul inconvénient : vous pouvez remplacer tous les membres des instances de cette classe lors de l'instanciation, y compris les méthodes et les propriétés privées qui ne devraient jamais être remplacés.  

En plus, il existe d'autres limites:

  • Ext.apply ne fusionne pas les propriétés de l'objet de manière récursive. Donc dans cet exemple, vous ne pouvez pas remplacer bottomBar.height à 60, par exemple, sans fournir d'autres propriétés par défaut de bottomBar.

  •  Getters et setters doivent être définis manuellement pour chaque propriété de configuration. Il n'est pas possible de spécifier clairement quelles sont les propriétés de configuration, par conséquent, setters et getters ne peut pas être généré automatiquement.

 La nouvelle méthode :

 

En Ext JS 4, nous introduisons une propriété config  :

 

Ext.define('My.own.Window', {
   /** @readonly */
    isWindow: true,

    config: {
        title: 'Title Here',

        bottomBar: {
            enabled: true,
            height: 50,
            resizable: false
        }
    },

    constructor: function(config) {
        this.initConfig(config);

        return this;
    },

    applyTitle: function(title) {
        if (!Ext.isString(title) || title.length === 0) {
            alert('Error: Title must be a valid non-empty string');
        }
        else {
            return title;
        }
    },

    applyBottomBar: function(bottomBar) {
        if (bottomBar && bottomBar.enabled) {
            if (!this.bottomBar) {
                return Ext.create('My.own.WindowBottomBar', bottomBar);
            }
            else {
                this.bottomBar.setConfig(bottomBar);
            }
        }
    }
});

 

Et voici un exemple de la façon dont il peut être utilisé :

 

var myWindow = Ext.create('My.own.Window', {
    title: 'Hello World',
    bottomBar: {
        height: 60
    }
});

alert(myWindow.getTitle()); // alerts "Hello World"

myWindow.setTitle('Something New');

alert(myWindow.getTitle()); // alerts "Something New"

myWindow.setTitle(null); // alerts "Error: Title must be a valid non-empty string"

myWindow.setBottomBar({ height: 100 }); // Bottom bar's height is changed to 100

 

Grâce à ces changements:

  • Le code de My.own.Window class' est considérablement réduit
  • les propriétés de configurations sont completement encapsulés et isolé des autres propriéts
  • Les méthodes Getter and setter, sont généré automatiquement lors d ela création de la classe, si ces methodes ne sont pas déjà définies.
  • La méthode apply  est également généré pour chaque propriété de configuration. La méthode de définition auto-généré appelle la méthode apply en interne avant de définir la valeur. Override the apply method for a config property if you need to run custom logic before setting the value. If apply does not return a value then the setter will not set the value. For example see applyTitle above.

Statics

Les membres statiques peuvent être définies en utilisant la config statics.

 

Ext.define('Computer', {
    statics: {
        instanceCount: 0,
        factory: function(brand) {
            // 'this' in static methods refer to the class itself
            return new this({brand: brand});
        }
    },

    config: {
        brand: null
    },

    constructor: function(config) {
        this.initConfig(config);

        // the 'self' property of an instance refers to its class
        this.self.instanceCount ++;

        return this;
    }
});

var dellComputer = Computer.factory('Dell');
var appleComputer = Computer.factory('Mac');

alert(appleComputer.getBrand()); // using the auto-generated getter to get the value of a config property. Alerts "Mac"

alert(Computer.instanceCount); // Alerts "2"

Héritage

Ext JS 4 prend en charge l'héritage à travers subclassing et  mixins. Pour plus d'informations sur l'héritage consultez la documentation de Ext.Class

Les dépendances

Une autre nouvelle fonctionnalité introduite dans Ext JS 4 est le chargement dynamique des dépendances. Pour plus d'informations consultez la documentation de Ext.Loader