3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.data.Tree
18 * This class is used as a container for a series of nodes. The nodes themselves maintain
19 * the relationship between parent/child. The tree itself acts as a manager. It gives functionality
20 * to retrieve a node by its identifier: {@link #getNodeById}.
22 * The tree also relays events from any of it's child nodes, allowing them to be handled in a
23 * centralized fashion. In general this class is not used directly, rather used internally
24 * by other parts of the framework.
27 Ext.define('Ext.data.Tree', {
31 observable: "Ext.util.Observable"
35 * @property {Ext.data.NodeInterface}
36 * The root node for this tree
41 * Creates new Tree object.
42 * @param {Ext.data.NodeInterface} root (optional) The root node
44 constructor: function(root) {
49 me.mixins.observable.constructor.call(me);
57 * Returns the root node for this tree.
58 * @return {Ext.data.NodeInterface}
60 getRootNode : function() {
65 * Sets the root node for this tree.
66 * @param {Ext.data.NodeInterface} node
67 * @return {Ext.data.NodeInterface} The root node
69 setRootNode : function(node) {
73 Ext.data.NodeInterface.decorate(node);
75 if (me.fireEvent('beforeappend', null, node) !== false) {
76 node.set('root', true);
79 me.relayEvents(node, [
82 * @alias Ext.data.NodeInterface#append
88 * @alias Ext.data.NodeInterface#remove
94 * @alias Ext.data.NodeInterface#move
100 * @alias Ext.data.NodeInterface#insert
105 * @event beforeappend
106 * @alias Ext.data.NodeInterface#beforeappend
111 * @event beforeremove
112 * @alias Ext.data.NodeInterface#beforeremove
118 * @alias Ext.data.NodeInterface#beforemove
123 * @event beforeinsert
124 * @alias Ext.data.NodeInterface#beforeinsert
130 * @alias Ext.data.NodeInterface#expand
136 * @alias Ext.data.NodeInterface#collapse
141 * @event beforeexpand
142 * @alias Ext.data.NodeInterface#beforeexpand
147 * @event beforecollapse
148 * @alias Ext.data.NodeInterface#beforecollapse
154 * Fires whenever the root node is changed in the tree.
155 * @param {Ext.data.Model} root The new root
162 insert: me.onNodeInsert,
163 append: me.onNodeAppend,
164 remove: me.onNodeRemove
168 me.registerNode(node);
169 me.fireEvent('append', null, node);
170 me.fireEvent('rootchange', node);
177 * Flattens all the nodes in the tree into an array.
179 * @return {Ext.data.NodeInterface[]} The flattened nodes.
183 hash = this.nodeHash,
187 if (hash.hasOwnProperty(key)) {
188 nodes.push(hash[key]);
195 * Fired when a node is inserted into the root or one of it's children
197 * @param {Ext.data.NodeInterface} parent The parent node
198 * @param {Ext.data.NodeInterface} node The inserted node
200 onNodeInsert: function(parent, node) {
201 this.registerNode(node, true);
205 * Fired when a node is appended into the root or one of it's children
207 * @param {Ext.data.NodeInterface} parent The parent node
208 * @param {Ext.data.NodeInterface} node The appended node
210 onNodeAppend: function(parent, node) {
211 this.registerNode(node, true);
215 * Fired when a node is removed from the root or one of it's children
217 * @param {Ext.data.NodeInterface} parent The parent node
218 * @param {Ext.data.NodeInterface} node The removed node
220 onNodeRemove: function(parent, node) {
221 this.unregisterNode(node, true);
225 * Gets a node in this tree by its id.
227 * @return {Ext.data.NodeInterface} The match node.
229 getNodeById : function(id) {
230 return this.nodeHash[id];
234 * Registers a node with the tree
236 * @param {Ext.data.NodeInterface} The node to register
237 * @param {Boolean} [includeChildren] True to unregister any child nodes
239 registerNode : function(node, includeChildren) {
240 this.nodeHash[node.getId() || node.internalId] = node;
241 if (includeChildren === true) {
242 node.eachChild(function(child){
243 this.registerNode(child, true);
249 * Unregisters a node with the tree
251 * @param {Ext.data.NodeInterface} The node to unregister
252 * @param {Boolean} [includeChildren] True to unregister any child nodes
254 unregisterNode : function(node, includeChildren) {
255 delete this.nodeHash[node.getId() || node.internalId];
256 if (includeChildren === true) {
257 node.eachChild(function(child){
258 this.unregisterNode(child, true);
266 * @param {Function} sorterFn The function to use for sorting
267 * @param {Boolean} recursive True to perform recursive sorting
269 sort: function(sorterFn, recursive) {
270 this.getRootNode().sort(sorterFn, recursive);
276 * @param {Function} sorterFn The function to use for filtering
277 * @param {Boolean} recursive True to perform recursive filtering
279 filter: function(filters, recursive) {
280 this.getRootNode().filter(filters, recursive);