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

yizhihongxing

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实现日期计算器功能

    非常感谢您对“原生js实现日期计算器功能”的关注。下面是我对这个话题的详细讲解,希望能够帮助到您。 什么是日期计算器功能? 日期计算器功能指的是在网页上实现日期的计算,如计算两个日期之间相差的天数、周数、月数、年数等等。这个功能在实际的项目中很常见,比如生日计算器、工作日计算器等等。 使用JavaScript实现日期计算器功能 原生JavaScript能够轻…

    JavaScript 2023年5月27日
    00
  • 使用闭包对setTimeout进行简单封装避免出错

    对于JavaScript定时器setTimeout,常常在一些复杂的场景下使用,但由于其特性,在使用过程中,可能会出现回调函数中的this关键字指向不明的问题,或者定时器句柄无法被清除的问题等。这时,我们可以使用闭包对setTimeout进行简单的封装,以避免出错。下面是具体的攻略: 1. 封装setTimeout 首先,我们要封装setTimeout函数。…

    JavaScript 2023年6月10日
    00
  • thinkphp3.x中cookie方法的用法分析

    ThinkPHP3.x中cookie方法的用法分析 什么是Cookie Cookie(又称为 HTTP cookie 或者 Web cookie)是指在访问网站时,由网站服务器发送给浏览器的一小段数据,然后浏览器将数据保存在本地硬盘上,每次访问该网站时将数据发送给网站服务器。Cookie 目的在于记录站点统计信息、用户习惯、购物车内容或者保存用户账号密码等。…

    JavaScript 2023年6月1日
    00
  • ES6(ECMAScript 6)新特性之模板字符串用法分析

    ES6(ECMAScript 6)新特性之模板字符串用法分析 1. 模板字符串的概念 模板字符串是ES6(ECMAScript 6)中的一项新特性,用来处理复杂的字符串拼接操作。它使用反引号字符 (`) 来表示字符串,可以直接在字符串中插入变量和表达式。 2. 模板字符串的基本用法 2.1 普通字符串的拼接 在使用模板字符串之前,我们可以先来了解一下普通字符…

    JavaScript 2023年5月28日
    00
  • 10个比较流行的JavaScript面试题

    这里是关于“10个比较流行的JavaScript面试题”的完整攻略: 1. 什么是变量提升 变量提升是JavaScript语言中的一种特性,它让变量可以在声明之前使用。在JavaScript代码执行前,变量的声明会被“提升”到代码的顶端。这意味着即使在变量声明之前使用变量,JavaScript引擎也会在代码执行时正常处理它。 示例: console.log(…

    JavaScript 2023年5月27日
    00
  • javascript之Array 数组对象详解

    JavaScript之Array数组对象详解 什么是数组 在 JavaScript 中,数组(Array)是一种复合数据类型,用于存储一组有序的数据。可以将数组看作是一个盒子,该盒子中可以存放多个数据,而且这些数据是有序的,通过下标(索引)来访问每一个数据。 数组的创建 JavaScript 中,可以使用两种方式来创建数组: 1. 使用字面量方式创建数组 l…

    JavaScript 2023年5月27日
    00
  • jQuery通过写入cookie实现更换网页背景的方法

    jQuery 通过写入 cookie 实现更换网页背景的方法,实际上就是利用 cookie 存储用户选择的网页背景样式及其对应的 CSS 样式类名,在页面加载时根据 cookie 中存储的样式类名来设置页面背景样式。 具体实现步骤如下: 1. HTML 结构 在 HTML 文档的 head 标签中引入 jQuery 库和自定义 js 文件。 <!DOC…

    JavaScript 2023年6月11日
    00
  • javascript prototype 原型链

    JavaScript 中的每一个对象都有一个指向另一个对象的内部链接,这个链接称为原型(prototype)链。如果一个对象需要一个属性或者方法,但是它本身并没有这个属性或方法,它会沿着自身的原型链向上查找,直到找到该属性或方法为止。 原型链的概念 每一个 JavaScript 对象在创建时,都会与一个 “原型” 关联起来,这个原型可以是其他的对象的实例,这…

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