官术网_书友最值得收藏!

Building custom JavaScript classes that inherit the functionality of Ext JS

You can incorporate features of Ext JS into your own JavaScript classes. For example, the ObservableList class created in this recipe will use the features of the framework's Ext.util.Observable class to fire notifications when items are added, removed, or when the list is cleared. The list's interface will be as follows:

  • add(object): A function that inserts an item in the list and returns the position into which the item was inserted
  • insert(index, object): A function that inserts an item to the List at the specified index
  • item(index): A function that returns the element at the specified index
  • remove(object): A function to remove the first occurrence of a specific object
  • removeAt(index): A function in charge of removing the item at the specified index
  • each(fn, scope): A method that executes the specified function once for every item in the list
  • clear(): A function to remove all items from the list
  • add: An event signaling that an element was added
  • remove: An event notifying that an element was removed
  • clear: An event signaling that the list was cleared

How to do it...

Let's proceed to build and test the ObservableList class as shown in the following steps:

  1. Define the ObservableList class:
    Ext.namespace("Samples");
    Samples.ObservableList = function() {
    this.items = [];
    this.length = 0;
    // The events our custom class will expose.
    // The parent Class, Observable, will handle event publishing
    //for us.
    this.addEvents("add", "remove", "clear");
    Samples.ObservableList.superclass.constructor.call(this);
    };
    
  2. Inherit the Observable class's functionality by establishing our class as an extension of Observable:
    Ext.extend(Samples.ObservableList, Ext.util.Observable, {
    //Disable having functions as items.
    allowFunctions: false,
    //Our Class members go here...
    });
    
    
  3. Now, implement our class's interface:
    Ext.extend(Samples.ObservableList, Ext.util.Observable, {
    allowFunctions: false,
    //Adds an item to the list and
    //returns the position into which the new element was inserted.
    add: function(o) {
    this.items.push(o);
    this.length++;
    // Fire the add event, returning the position
    // into which the new element was inserted.
    pos = this.length - 1;
    this.fireEvent("add", pos);
    return pos;
    },
    // Inserts an item to the List at the specified index.
    insert: function(index, o) {
    //If the index is outside the list, insert the element at
    // the end of the list.
    if (index >= this.length) {
    return this.add(o);
    }
    this.length++;
    this.items.splice(index, 0, o);
    this.fireEvent("add", index);
    },
    // Removes all items from the list.
    clear: function() {
    this.length = 0;
    this.items = [];
    this.fireEvent("clear");
    },
    // Determines the index of a specific item in the list.
    indexOf: function(o) {
    return this.items.indexOf(o);
    },
    // Determines whether the List contains a specific value.
    contains: function(o) {
    return this.indexOf(o) != -1;
    },
    // Our enumerator function. Executes the specified function
    //once for every element in the list.
    each: function(fn, scope) {
    var items = [].concat(this.items); for (var i = 0, len = items.length; i < len; i++) {
    if (fn.call(scope || items[i], items[i], i, len) === false) {
    break;
    }
    }
    },
    // Removes the item at the specified index.
    removeAt: function(index) {
    if (index < this.length && index >= 0) {
    this.length--;
    var o = this.items[index];
    this.items.splice(index, 1);
    this.fireEvent("remove", o);
    }
    },
    // Removes the first occurrence of a specific object.
    remove: function(o) {
    this.removeAt(this.indexOf(o));
    },
    // Return the element at the specified index.
    item: function(index) {
    var item = this.items[index];
    return item;
    }
    });
    Samples.ObservableList.prototype.get = Samples.ObservableList.prototype.item;
    
  4. It's time to test our class. Let's do it as follows:
    Ext.onReady(function() {
    list = new Samples.ObservableList();
    for (var i = 0; i < 15; i++) {
    pos = list.add("test " + i);
    }
    // Add handlers for the list's events.
    list.on("remove", function(o) {
    alert("Removed: " + o);
    });
    list.on("add", function(index) {
    alert("Added at position: " + index);
    });
    list.on("clear", function() {
    alert("List length is: " + list.length);
    });
    document.write("List length is " + list.length + "<br/>");
    // Insert an additional element and
    //check that the add event fires.
    var index = 2;
    list.insert(index, "A new item");
    document.write("Just inserted: " + list.item(index) + "<br/>");
    document.write("List length is: " + list.length + "<br/>");
    // Remove an item an verify that the remove event fires.
    index = 5;
    document.write("Removing item at position" + index + "<br/>");
    list.removeAt(index);
    document.write("List length after removal: " + list.length + "<br/>");
    document.write("Clearing list...<br/>");
    // Remove all items and check that the clear event fires.
    list.clear();
    document.write("List length after clear: " + list.length + "<br/>");
    });
    
    

How it works...

A powerful mechanism for extending classes is provided by Ext JS with Ext.extend(subclass, superclass, [overrides]). This function allows you to extend one class with another class and, optionally, to override the superclass's members.

Our example first defines the custom ObservableList class and passes its events to the parent, Ext.Observable. It then uses Ext.extend(subclass, superclass, [overrides]) not only to establish that the custom class implements Ext.Observable, but also to define the bulk of its own interface—the add(object), insert(index, object), clear(), indexOf(object), each(fn, scope), removeAt(index), remove(object), and item(index) functions.

Multiple versions of this approach are used by Ext JS to define its own class hierarchy. I encourage you to examine the source code of the library in order to get familiar with them.

See also...

  • The Adding features to the Ext JS classes recipe, covered earlier in this chapter, explains how to add new functions to the Ext JS classes
  • The A custom column layout recipe from Chapter 2 is an example of how to extend the native Ext JS layouts
  • The A three-panel application layout with one line of code recipe from Chapter 2 shows how to build a reusable Ext JS component that encapsulates a three-panel layout
主站蜘蛛池模板: 延寿县| 德州市| 吉木乃县| 遂平县| 固始县| 美姑县| 柘城县| 阜城县| 铜梁县| 汪清县| 开鲁县| 双鸭山市| 长治县| 安宁市| 横峰县| 河北区| 金寨县| 永和县| 庄浪县| 平舆县| 石泉县| 互助| 蒲江县| 禄劝| 木兰县| 万载县| 精河县| 铁岭县| 牟定县| 华安县| 涪陵区| 彰武县| 呼和浩特市| 梧州市| 德兴市| 浦城县| 八宿县| 大埔区| 宣恩县| 故城县| 塔河县|