extjs关于treePanel+chekBox全部选中以及清空选中问题探讨

ExtJS关于TreePanel+CheckBox全部选中以及清空选中问题探讨

1. CheckBox的状态问题

在使用ExtJS的TreePanel时,节点如果要使用CheckBox,需要在NodeInterface中添加配置:

Ext.define('MyApp.model.MyTreeNode', {
    extend: 'Ext.data.TreeModel',
    mixins: ['Ext.mixin.Observable'],
    requires: [
        'Ext.data.proxy.Memory',
        'Ext.data.identifier.UUID'
    ],
    /**
     * NodeInterface配置
     */
    statics: {
        nodeInterface: {
            // 下面两个配置和CheckBox有关
            checked: false, // 默认不选中
            expandable: true // 点击CheckBox时自动展开或折叠子节点
        }
    },
    fields: [
        {name: 'text', type: 'string'},
        // 其他属性
    ]
});

在配置完成后,通过TreePanel的选择事件控制CheckBox的选中状态:

Ext.create('Ext.tree.Panel', {
    // 其他配置
    listeners: {
        /**
         * 选择事件
         * @param {Ext.selection.TreeModel} selModel 选择模型
         * @param {Ext.data.TreeModel}       record   点击的 node
         * @param {number}                  index    node 索引
         * @param {object}                  eOpts
         */
        select: function(selModel, record, index, eOpts){
            if (record && record.childNodes.length > 0){
                var checked = record.get('checked');
                for (i = 0; i < record.childNodes.length; i++){
                    record.childNodes[i].set('checked', checked);
                }
            }
        }
    }
});

在上面的代码中,判断当前点击的节点是否有子节点,如果有,则将子节点的选中状态与当前节点相同。

但是,如果一个节点被选中,那么它的所有父节点也应该被选中。我们需要根据这个原则更新父节点的状态。

可以使用以下代码:

/**
 * 更新指定节点的父节点选中状态
 * @param {Ext.data.TreeModel} node
 */
function updateCheckedParent(node){
    var parentNode = node.parentNode;
    if (parentNode){
        // 判断是否所有子节点都被选中,如果是,则选中父节点;否则,取消选中父节点
        var allChecked = true;
        for (i = 0; i < parentNode.childNodes.length; i++){
            if (parentNode.childNodes[i].get('checked') !== true){
                allChecked = false;
                break;
            }
        }
        parentNode.set('checked', allChecked);
        updateCheckedParent(parentNode);
    }
}

在每次选择事件结束时,调用该函数更新父节点的状态:

Ext.create('Ext.tree.Panel', {
    // 其他配置
    listeners: {
        /**
         * 选择事件
         * @param {Ext.selection.TreeModel} selModel 选择模型
         * @param {Ext.data.TreeModel}       record   点击的 node
         * @param {number}                  index    node 索引
         * @param {object}                  eOpts
         */
        select: function(selModel, record, index, eOpts){
            if (record && record.childNodes.length > 0){
                var checked = record.get('checked');
                for (i = 0; i < record.childNodes.length; i++){
                    record.childNodes[i].set('checked', checked);
                }
                updateCheckedParent(record);
            }
        }
    }
});

现在,我们已经完成了所有节点的选中或取消选中。但是,我们还需要实现两个特殊的按钮功能:全部选中和清空选中。

2. 全部选中按钮

当我们点击全部选中按钮时,需要遍历所有节点,将它们的选中状态都设置为 true:

/**
 * 遍历所有节点,将它们的选中状态设置为 true
 * @param {Ext.tree.Panel} tree TreePanel面板
 */
function checkAll(tree){
    tree.getRootNode().cascadeBy(function(node){
        node.set('checked', true);
    });
}

3. 清空选中按钮

当我们点击清空选中按钮时,需要遍历所有节点,将它们的选中状态都设置为 false:

/**
 * 遍历所有节点,将它们的选中状态设置为 false
 * @param {Ext.tree.Panel} tree TreePanel面板
 */
function uncheckAll(tree){
    tree.getRootNode().cascadeBy(function(node){
        node.set('checked', false);
    });
}

完整的示例代码如下:

Ext.create('Ext.tree.Panel', {
    renderTo: 'tree',
    title: 'Sample Tree',
    width: 350,
    height: 300,
    rootVisible: false,
    store: Ext.create('Ext.data.TreeStore', {
        model: 'MyApp.model.MyTreeNode',
        proxy: {
            type: 'memory',
            reader: {
                type: 'json',
                rootProperty: 'children'
            }
        },
        root: {
            expanded: true,
            children: [
                // 树的数据
            ]
        }
    }),
    columnLines: true,
    viewConfig: {
        stripeRows: false,
        listeners: {
            /**
             * 渲染后执行
             * @param {Ext.tree.View} view TreeView视图
             */
            afterrender: function(view){
                // 渲染后创建按钮
                var toolbar = view.up('panel').addDocked({
                    xtype: 'toolbar',
                    dock: 'top',
                    items: [
                        {
                            text: '全部选中',
                            glyph: 'xf00c@FontAwesome',
                            handler: function(){
                                checkAll(view.up('treepanel'));
                            }
                        },
                        {
                            text: '清空选中',
                            glyph: 'xf00d@FontAwesome',
                            handler: function(){
                                uncheckAll(view.up('treepanel'));
                            }
                        }
                    ]
                })[0];
                // 为按钮添加样式类
                toolbar.items.items.forEach(function(item){
                    item.setGlyphCls('toolbar-glyph toolbar-glyph-big');
                });
            },
            /**
             * 选择事件
             * @param {Ext.selection.TreeModel} selModel 选择模型
             * @param {Ext.data.TreeModel}       record   点击的 node
             * @param {number}                  index    node 索引
             * @param {object}                  eOpts
             */
            select: function(selModel, record, index, eOpts){
                if (record && record.childNodes.length > 0){
                    var checked = record.get('checked');
                    for (i = 0; i < record.childNodes.length; i++){
                        record.childNodes[i].set('checked', checked);
                    }
                    updateCheckedParent(record);
                }
            }
        }
    }
});

/**
 * 更新指定节点的父节点选中状态
 * @param {Ext.data.TreeModel} node
 */
function updateCheckedParent(node){
    var parentNode = node.parentNode;
    if (parentNode){
        // 判断是否所有子节点都被选中,如果是,则选中父节点;否则,取消选中父节点
        var allChecked = true;
        for (i = 0; i < parentNode.childNodes.length; i++){
            if (parentNode.childNodes[i].get('checked') !== true){
                allChecked = false;
                break;
            }
        }
        parentNode.set('checked', allChecked);
        updateCheckedParent(parentNode);
    }
}

/**
 * 遍历所有节点,将它们的选中状态设置为 true
 * @param {Ext.tree.Panel} tree TreePanel面板
 */
function checkAll(tree){
    tree.getRootNode().cascadeBy(function(node){
        node.set('checked', true);
    });
}

/**
 * 遍历所有节点,将它们的选中状态设置为 false
 * @param {Ext.tree.Panel} tree TreePanel面板
 */
function uncheckAll(tree){
    tree.getRootNode().cascadeBy(function(node){
        node.set('checked', false);
    });
}

以上就是关于ExtJS关于TreePanel+CheckBox全部选中以及清空选中问题探讨的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:extjs关于treePanel+chekBox全部选中以及清空选中问题探讨 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • JS中比Switch…Case更优雅的多条件判断写法

    JS中使用Switch…Case方式进行多条件判断的常见缺点是比较冗长,不够简洁和优雅。本文将为大家介绍一种利用对象字面量来进行多条件判断的方式,来让代码更加优雅和易读。 使用对象字面量进行多条件判断的写法 使用对象字面量方式进行多条件判断,我们可以通过JS对象属性来表示条件判断中的每个case,通过函数属性来表示每个case对应的逻辑操作。示例如下: …

    JavaScript 2023年6月11日
    00
  • Python用requests-html爬取网页的实现

    下面是一份完整的“Python用requests-html爬取网页的实现”攻略。 Python用requests-html爬取网页的实现 requests-html 是Python requests库的一个扩展,它为Python开发者提供了一个更为简洁、优雅的HTML解析器。 安装requests-html 要使用requests-html,您首先需要通过p…

    JavaScript 2023年5月28日
    00
  • 深入理解JavaScript 闭包究竟是什么

    深入理解JavaScript 闭包究竟是什么 什么是闭包? 在JavaScript中,闭包是一种特殊的函数。它可以访问它外部作用域中的变量和函数,即使外部函数已经执行完毕,内部函数仍然可以访问外部函数中的变量和函数。这是因为JavaScript采用了词法作用域,并通过作用域链来保存变量和函数。 闭包的应用 保存变量 由于闭包可以访问外部作用域中的变量,因此可…

    JavaScript 2023年6月10日
    00
  • Zend Framework处理Json数据方法详解

    Zend Framework处理Json数据方法详解 什么是Json? Json(JavaScript Object Notation)是一种轻量级数据交互格式,易于阅读和编写,同时易于机器解析和生成。Json格式是基于JavaScript语言的一个子集,但是Json是独立于语言的。Json数据结构包括对象、数组、值、字符串和Boolean值。 使用Zend…

    JavaScript 2023年5月28日
    00
  • 如何在CocosCreator中做一个List

    现在我来为您详细讲解如何在CocosCreator中做一个List的完整攻略。 1、创建List节点 首先我们需要在CocosCreator中用节点编辑器来创建一个List节点。创建节点的方式可以在菜单栏中选择Creator > Create Node。然后输入节点的名称并点击确定,此时我们将会得到一个空的节点。 2、添加List组件 在这个空节点上添…

    JavaScript 2023年6月11日
    00
  • JS实现的base64加密、md5加密及sha1加密详解

    JS实现的base64加密、md5加密及sha1加密详解 什么是base64加密 Base64是一种基于64个可打印字符来表示二进制数据的方法。在某些场景下,网络传输只支持传输ASCII字符,但是需要传输二进制数据时,使用Base64编码可以将二进制数据转换为ASCII字符,便于传输。 在JavaScript中,可以使用代码库 btoa() 方法来实现Bas…

    JavaScript 2023年5月28日
    00
  • 详解Javascript事件驱动编程

    详解Javascript事件驱动编程攻略 Javascript事件驱动编程是Javascript开发中一个重要的概念,它可以让编写的网页更有交互性。本攻略将详细地介绍Javascript事件驱动编程的概念、方法和注意事项。 概念 Javascript事件驱动编程是一种编程范式,它的核心思想是通过触发事件来执行代码。在Web开发中,当用户与网页发生交互时(比如…

    JavaScript 2023年5月27日
    00
  • js处理json以及字符串的比较等常用操作

    针对JS处理JSON以及字符串的比较等常用操作,我为您提供以下攻略: 处理JSON JSON的介绍 首先,需要了解一下JSON的基础知识。JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于JavaScript的一个子集,通过对象和数组的组合来表示数据。JSON格式的数据在所有支持JSON的编程语言中都可以使用,…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部