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获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】

    JS获取日期的方法实例【昨天,今天,明天,前n天,后n天的日期】 在JavaScript中,可以使用Date对象来获取当前时间和日期,并对其进行一些简单和复杂的操作。为了方便起见,以下是获取日期的常见方法实例: 获取当前日期 要获取当前日期,可以使用以下代码: let today = new Date(); let year = today.getFullY…

    JavaScript 2023年5月27日
    00
  • javascript 操作文件 实现方法小结

    Javascript 操作文件 实现方法小结 在Javascript中,操作文件的方法主要是使用File API和XMLHttpRequest对象的responseText、responseXML属性。 File API 1. 读取文件内容 使用File API的读取文件内容主要有以下几个步骤: 创建一个FileReader对象 调用FileReader对象…

    JavaScript 2023年5月27日
    00
  • HTML5 history新特性pushState、replaceState及两者的区别

    HTML5中引入的history API,包括pushState、replaceState方法的新特性,允许JavaScript程序修改浏览器的历史记录。在介绍这两个新特性的区别之前,我们先来了解一下它们的定义以及常见的使用场景。 pushState方法 pushState方法可以往浏览器历史记录里面插入一条新的记录,并在页面URL上添加指定的参数,而不需要…

    JavaScript 2023年6月11日
    00
  • window.location.hash 属性使用说明

    当浏览器地址栏中的URL中包含hash值(即以#开头的字符串),浏览器会自动将hash值存储到window.location.hash属性中。这个属性提供了一种用于操作hash值的方式,允许我们通过JavaScript动态地更改hash值,使得页面可以根据hash值的不同来展示不同的内容。 1. 获取当前页面的hash值 可以通过window.locatio…

    JavaScript 2023年6月11日
    00
  • Electron vue的使用教程图文详解

    Electron Vue的使用教程图文详解 Electron Vue是一款基于Electron和Vue的框架,可以用于快速构建桌面应用。本文将详细讲解如何使用Electron Vue构建桌面应用程序。 前置条件 在开始使用Electron Vue之前,需要具备以下技能和工具: 基本的HTML、CSS和JavaScript技能 Vue.js的基础知识 Node…

    JavaScript 2023年6月11日
    00
  • 替代window.event.srcElement效果的可兼容性的函数

    替代window.event.srcElement的可兼容性函数,可以使用event.target属性来获取触发事件的元素。但是需要注意的是,此方法在IE8及以下版本不兼容,需要做兼容处理。 下面是完整的攻略,包含两条示例说明: 1. 使用event.target属性获取元素 使用event.target属性可获取触发事件的元素,示例如下: function…

    JavaScript 2023年6月10日
    00
  • JavaScript奇技淫巧44招【实用】

    JavaScript奇技淫巧44招【实用】攻略 作为一名网站开发者,熟练掌握JavaScript的技巧和小技巧是非常重要的。下面是44个实用的JavaScript奇技淫巧,以及它们的用法和示例说明。 1. 使用逻辑运算符和函数默认值进行简化 function multiply(a, b) { b = typeof b !== ‘undefined’ ? b …

    JavaScript 2023年5月18日
    00
  • JavaScript通过filereader接口读取文件

    下面详细讲解JavaScript通过filereader接口读取文件的完整攻略: 1. Filereader介绍 FileReader是H5新增的文件读取对象,通过FileReader对象,web应用程序可以异步读取存储在用户计算机上的文件内容,使用FileReader可以读取文本、图片(base64字符串)、音频和视频等格式的文件。下面我们将介绍如何利用F…

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