【问题标题】:How can I filter a TreeStore in ExtJS 6.2?如何在 ExtJS 6.2 中过滤 TreeStore?
【发布时间】:2016-10-13 16:07:38
【问题描述】:

我需要过滤树(通过将文本与节点属性进行比较来搜索节点)。

这个fiddle 正是我所需要的,但它似乎不适用于 ExtJS 6.2。

在试图找出我的代码有什么问题之后,我决定简单地将 fiddle 中的框架版本从 4.2.1(默认)更改为 6.2.981 经典灰色,并且可以看到代码已过时(删除所有节点或任意数量我不明白为什么)。

有人可以验证该代码并告诉我如何将其移植到 v6.2 吗?

编辑:

差不多了。这段代码正在完成这项工作,但在深层 2 中停止,而不是所有树:JSFiddle

Ext.define('TreeFilter', {
    extend: 'Ext.AbstractPlugin',
    alias: 'plugin.treefilter',
    collapseOnClear: true, // collapse all nodes when clearing/resetting the filter
    allowParentFolders: false, // allow nodes not designated as 'leaf' (and their child items) to  be matched by the filter

    init: function(tree) {
        var me = this;
        me.tree = tree;

        tree.filter = Ext.Function.bind(me.filter, me);
        tree.clearFilter = Ext.Function.bind(me.clearFilter, me);
    },


    filter: function(value, property, re) {
            var me = this,
                tree = me.tree,
                matches = [], // array of nodes matching the search criteria
                root = tree.getRootNode(), // root node of the tree
                property = property || 'text', // property is optional - will be set to the 'text' propert of the  treeStore record by default
                re = re || new RegExp(value, "ig"), // the regExp could be modified to allow for case-sensitive, starts  with, etc.
                visibleNodes = [], // array of nodes matching the search criteria + each parent non-leaf  node up to root
                viewNode;

            if (Ext.isEmpty(value)) { // if the search field is empty
                me.clearFilter();
                return;
            }

            tree.expandAll(); // expand all nodes for the the following iterative routines

            // iterate over all nodes in the tree in order to evalute them against the search criteria
            root.cascadeBy(function(node) {
                if (node.get(property).match(re)) { // if the node matches the search criteria and is a leaf (could be  modified to searh non-leaf nodes)
                    matches.push(node) // add the node to the matches array
                }
            });

            if (me.allowParentFolders === false) { // if me.allowParentFolders is false (default) then remove any  non-leaf nodes from the regex match
                Ext.each(matches, function(match) {
                    if (!match.isLeaf()) {
                        Ext.Array.remove(matches, match);
                    }
                });
            }

            Ext.each(matches, function(item, i, arr) { // loop through all matching leaf nodes
                root.cascadeBy(function(node) { // find each parent node containing the node from the matches array
                    if (node.contains(item) == true) {
                        visibleNodes.push(node) // if it's an ancestor of the evaluated node add it to the visibleNodes  array
                    }
                });
                if (me.allowParentFolders === true && !item.isLeaf()) { // if me.allowParentFolders is true and the item is  a non-leaf item
                    item.cascadeBy(function(node) { // iterate over its children and set them as visible
                        visibleNodes.push(node)
                    });
                }
                visibleNodes.push(item) // also add the evaluated node itself to the visibleNodes array
            });

            root.cascadeBy(function(node) { // finally loop to hide/show each node
                viewNode = Ext.fly(tree.getView().getNode(node)); // get the dom element assocaited with each node
                if (viewNode) { // the first one is undefined ? escape it with a conditional
                    viewNode.setVisibilityMode(Ext.Element.DISPLAY); // set the visibility mode of the dom node to display (vs offsets)
                    viewNode.setVisible(Ext.Array.contains(visibleNodes, node));
                }
            });
        }

        ,
    clearFilter: function() {
        var me = this,
            tree = this.tree,
            root = tree.getRootNode();

        if (me.collapseOnClear) {
            tree.collapseAll();
        } // collapse the tree nodes
        root.cascadeBy(function(node) { // final loop to hide/show each node
            viewNode = Ext.fly(tree.getView().getNode(node)); // get the dom element assocaited with each node
            if (viewNode) { // the first one is undefined ? escape it with a conditional and show  all nodes
                viewNode.show();
            }
        });
    }
});


// EXAMPLE
var store = Ext.create('Ext.data.TreeStore', {
    root: {
        expanded: true,
        children: [{
            text: "detention",
            leaf: true
        }, {
            text: "homework",
            expanded: false,
            children: [{
                text: "book report",
                leaf: true
            }, {
                text: "algebra",
                leaf: true
            }]
        }, {
            text: "chores",
            expanded: false,
            children: [{
                text: "do homework",
                leaf: true
            }, {
                text: "walk dog",
                leaf: true
            }, {
                text: "clean room",
                leaf: true
            }, {
                text: "wash dishes",
                leaf: true
            }, {
                text: "laundry",
                leaf: true
            }]
        }, {
            text: "buy lottery tickets",
            leaf: true
        }, {
            text: "take over world",
            leaf: true
        }, {
            text: "Sencha",
            expanded: false,
            children: [{
                text: "Touch",
                expanded: false,
                children: [{
                    text: 'Viewport',
                    leaf: true
                }, {
                    text: 'Panel',
                    leaf: true
                }, {
                    text: 'Carousel',
                    leaf: true
                }]
            }, {
                text: "ExtJS",
                expanded: false,
                children: [{
                    text: 'viewport.Viewport',
                    leaf: true
                }, {
                    text: 'panel.Panel',
                    leaf: true
                }, {
                    text: 'tree.Panel',
                    leaf: true
                }]
            }]
        }]
    }
});

Ext.create('Ext.tree.Panel', {
    title: 'Simple Tree',
    width: 200,
    height: 150,
    store: store,
    rootVisible: false,
    renderTo: Ext.getBody(),
    plugins: [{
        ptype: 'treefilter',
        allowParentFolders: true
    }],
    dockedItems: [{
        xtype: 'toolbar',
        dock: 'top',
        items: [{
            xtype: 'trigger',
            triggerCls: 'x-form-clear-trigger',
            onTriggerClick: function() {
                this.reset();
                this.focus();
            },
            listeners: {
                change: function(field, newVal) {
                    var tree = field.up('treepanel');

                    tree.filter(newVal);
                },
                buffer: 250
            }
        }]
    }]
});

【问题讨论】:

  • 为什么是Ext.data.NodeStore 而不是Ext.data.TreeStore

标签: extjs4.2 extjs6-classic


【解决方案1】:

没有使用过滤器插件,我在更改事件中添加了一些有用的代码,它适用于所有深度。

"dockedItems": [{
        xtype: 'toolbar',
        dock: 'top',
        items: [{
                xtype: 'textfield', //As of Ext JS 5.0 trigger class has been deprecated.  It is recommended to use {@link Ext.form.field.Text Text Field}.
                triggerCls: 'x-form-clear-trigger',
                width: 300,
                onTriggerClick: function () {
                    this.reset();
                    this.focus();
                },
                listeners: {
                    change: function (field, newVal) {
                        var reportBuilderStore = field.up('panel').getStore();
                        if (!Ext.isEmpty(field.value)) {
                            reportBuilderStore.filterBy(function (rec) {
                                var childs = !Ext.isEmpty(rec.get('children')) ? rec.get('children').map(function (x) {
                                        return x.text;
                                    }) : [];
                                var matched = false;
                                for (var val of childs) {
                                    if (val.toUpperCase().match((field.value).toUpperCase())) {
                                        matched = true;
                                        break;
                                    }
                                }
                                if (!Ext.isEmpty(rec.get('text').toUpperCase().match((field.value).toUpperCase())) || rec.get('text').toUpperCase() == "ROOT" || matched)
                                    return true;
                            });
                        } else {
                            reportBuilderStore.clearFilter();
                        }
                    },
                    buffer: 250
                }
            }
        ]
    }
],

【讨论】:

  • 感谢您提供此代码 sn-p,它可能会提供一些有限的即时帮助。 proper explanation would greatly improve its long-term value 通过展示为什么这是一个很好的解决问题的方法,并将使其对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多