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

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
主站蜘蛛池模板: 齐河县| 郯城县| 嵊州市| 大庆市| 千阳县| 盐津县| 桐庐县| 兴山县| 北宁市| 始兴县| 商都县| 芦山县| 金溪县| 余干县| 临夏县| 平遥县| 崇明县| 咸丰县| 长武县| 双柏县| 手机| 漳浦县| 静乐县| 上杭县| 青浦区| 阿城市| 平舆县| 汨罗市| 衡山县| 建水县| 东阳市| 北川| 嘉荫县| 陇南市| 洛南县| 贺州市| 盘山县| 延安市| 化德县| 乌什县| 桐乡市|