2 * @class Ext.data.NodeStore
3 * @extends Ext.data.AbstractStore
7 Ext.define('Ext.data.NodeStore', {
8 extend: 'Ext.data.Store',
10 requires: ['Ext.data.NodeInterface'],
13 * @cfg {Ext.data.Record} node The Record you want to bind this Store to. Note that
14 * this record will be decorated with the Ext.data.NodeInterface if this is not the
20 * @cfg {Boolean} recursive Set this to true if you want this NodeStore to represent
21 * all the descendents of the node in its flat data collection. This is useful for
22 * rendering a tree structure to a DataView and is being used internally by
23 * the TreeView. Any records that are moved, removed, inserted or appended to the
24 * node at any depth below the node this store is bound to will be automatically
25 * updated in this Store's internal flat data structure.
30 * @cfg {Boolean} rootVisible <tt>false</tt> to not include the root node in this Stores collection (defaults to <tt>true</tt>)
34 constructor: function(config) {
38 config = config || {};
39 Ext.apply(me, config);
42 if (Ext.isDefined(me.proxy)) {
43 Ext.Error.raise("A NodeStore cannot be bound to a proxy. Instead bind it to a record " +
44 "decorated with the NodeInterface by setting the node config.");
48 config.proxy = {type: 'proxy'};
49 me.callParent([config]);
51 me.addEvents('expand', 'collapse', 'beforeexpand', 'beforecollapse');
60 setNode: function(node) {
63 if (me.node && me.node != node) {
64 // We want to unbind our listeners on the old node
66 expand: me.onNodeExpand,
67 collapse: me.onNodeCollapse,
68 append: me.onNodeAppend,
69 insert: me.onNodeInsert,
70 remove: me.onNodeRemove,
78 Ext.data.NodeInterface.decorate(node);
84 expand: me.onNodeExpand,
85 collapse: me.onNodeCollapse,
86 append: me.onNodeAppend,
87 insert: me.onNodeInsert,
88 remove: me.onNodeRemove,
93 if (node.isExpanded() && node.isLoaded()) {
94 me.onNodeExpand(node, node.childNodes, true);
99 onNodeSort: function(node, childNodes) {
102 if ((me.indexOf(node) !== -1 || (node === me.node && !me.rootVisible) && node.isExpanded())) {
103 me.onNodeCollapse(node, childNodes, true);
104 me.onNodeExpand(node, childNodes, true);
108 onNodeExpand: function(parent, records, suppressEvent) {
110 insertIndex = me.indexOf(parent) + 1,
111 ln = records ? records.length : 0,
114 if (!me.recursive && parent !== me.node) {
118 if (!me.isVisible(parent)) {
122 if (!suppressEvent && me.fireEvent('beforeexpand', parent, records, insertIndex) === false) {
127 me.insert(insertIndex, records);
128 for (i = 0; i < ln; i++) {
130 if (record.isExpanded()) {
131 if (record.isLoaded()) {
133 me.onNodeExpand(record, record.childNodes, true);
136 record.set('expanded', false);
143 if (!suppressEvent) {
144 me.fireEvent('expand', parent, records);
148 onNodeCollapse: function(parent, records, suppressEvent) {
151 collapseIndex = me.indexOf(parent) + 1,
154 if (!me.recursive && parent !== me.node) {
158 if (!suppressEvent && me.fireEvent('beforecollapse', parent, records, collapseIndex) === false) {
162 for (i = 0; i < ln; i++) {
165 if (record.isExpanded()) {
166 me.onNodeCollapse(record, record.childNodes, true);
170 if (!suppressEvent) {
171 me.fireEvent('collapse', parent, records, collapseIndex);
175 onNodeAppend: function(parent, node, index) {
179 if (me.isVisible(node)) {
183 sibling = node.previousSibling;
184 while (sibling.isExpanded() && sibling.lastChild) {
185 sibling = sibling.lastChild;
189 me.insert(me.indexOf(refNode) + 1, node);
190 if (!node.isLeaf() && node.isExpanded()) {
191 if (node.isLoaded()) {
193 me.onNodeExpand(node, node.childNodes, true);
196 node.set('expanded', false);
203 onNodeInsert: function(parent, node, refNode) {
205 index = this.indexOf(refNode);
207 if (index != -1 && me.isVisible(node)) {
208 me.insert(index, node);
209 if (!node.isLeaf() && node.isExpanded()) {
210 if (node.isLoaded()) {
212 me.onNodeExpand(node, node.childNodes, true);
215 node.set('expanded', false);
222 onNodeRemove: function(parent, node, index) {
224 if (me.indexOf(node) != -1) {
225 if (!node.isLeaf() && node.isExpanded()) {
226 me.onNodeCollapse(node, node.childNodes, true);
232 isVisible: function(node) {
233 var parent = node.parentNode;
235 if (parent === this.node && !this.rootVisible && parent.isExpanded()) {
239 if (this.indexOf(parent) === -1 || !parent.isExpanded()) {
243 parent = parent.parentNode;