Ext JS 4: Filtering a TreeStore

前端 未结 5 1260
闹比i
闹比i 2020-12-10 07:45

I originally posted this on the Sencha forums here but didn\'t get any responses (other than my own answer, which I will post soon), so I am going to repost it here and see

5条回答
  •  既然无缘
    2020-12-10 08:15

    I was looking for a way to filter a treestore so that if a filterBy function returned true for any node, I wanted to display the complete node hierarchy of that node including all the parent nodes, grand parent node, etc and child nodes, grand child node, etc. I modified it from the other solutions provided in this question. This solutions works recursively so the treestore can be of any size.

    Ext.override(Ext.data.TreeStore, {
    
            hasFilter: false,
    
            /**
            * Filters the current tree by a function fn
            * if the function returns true the node will be in the filtered tree
            * a filtered tree has also a flat structure without folders
            */
            filterBy : function(fn, scope) {
                var me    = this,
                nodes = [],
                root  = me.getRootNode(),
                tmp;
    
    
                // the snapshot holds a copy of the current unfiltered tree
                me.snapshot = me.snapshot || root.copy(null, true);
    
    
                tmp = me.snapshot.copy(null, true);
                var childNodes = tmp.childNodes;
                root.removeAll();
                for( var i=0; i < childNodes.length; i++ ) {
    
                    //Recursively tranverse through the root and adds the childNodes[i] if fn returns true
                    if( this.traverseNode( childNodes[i], root, fn ) == true ) {
                                     i--;
                                }
    
                }
    
                return me;
            },
    
            /**
            * Recursively tranverse through the root and adds the childNodes[i] if fn returns true
            */
            traverseNode: function( node, parentNode, fn ) {
    
                var me = this;
    
                if( fn.call( me, node ) ) {
                    parentNode.appendChild( node );
                    return true;
                }
    
                if( node.hasChildNodes() ) {
    
                    var childNodes = node.childNodes;
                    var found = false;
    
                    for( var i=0; i < childNodes.length; i++ ) {
                        if( this.traverseNode( childNodes[i], node, fn ) == true ) {
                            found = true;
                        }
                    }
    
                    if( found == true ) {
                        parentNode.appendChild( node );
                        return true;
                    }
                }
    
                return false;
            },
    
    
            /**
            * Clears all filters a shows the unfiltered tree
            */
            clearFilter : function() {
                var me = this;
    
                if (me.isFiltered()) {
                    me.setRootNode(me.snapshot);
                    delete me.snapshot;
                }
    
                return me;
            },
    
            /**
            * Returns true if the tree is filtered
            */
            isFiltered : function() {
                return !!this.snapshot;
            }
        });
    

    So it works with just like a regular store filterBy call.

    searchText = "searchText";
    store.filterBy( function(item) {
    
                var keys = item.fields.keys;
    
                for( var i=0; i < keys.length; i++ ) {
                    var value = item.get( keys[i] );
                    if( value != null ) {
                        if( value.toString().toLowerCase().indexOf( searchText ) !== -1 ) {
                            return true;
                        }
                    }
                }
    
                return false;
            });
    

提交回复
热议问题