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日

相关文章

  • 基于JavaScript 声明全局变量的三种方式详解

    当我们需要在JavaScript中定义一个全局变量时,我们可以使用以下三种方式: 1. 在全局作用域下声明变量 第一种方式是直接在全局作用域中声明变量,这样的变量就会成为全局变量。 // 直接在全局作用域中声明变量,成为全局变量 var globalVariable = ‘我是全局变量’; 上述代码中,使用 var 关键字直接声明一个变量 globalVar…

    JavaScript 2023年5月28日
    00
  • 浅谈JavaScript的内置对象和浏览器对象

    下面我来为你详细讲解“浅谈JavaScript的内置对象和浏览器对象”的完整攻略。 一、JavaScript的内置对象 JavaScript的内置对象包括全局对象、基础(原始)数据类型和引用数据类型。 1. 全局对象 全局对象是指JavaScript中可以在任何地方访问的对象。常见的全局对象有: Math:用于数学计算 Date:用于日期和时间 RegExp…

    JavaScript 2023年5月27日
    00
  • JavaScript实现显示隐藏表单文字

    当我们需要提供更多的内容或者选项时,经常会用到表单,但是大量的表单元素很容易造成页面的混乱。因此,有时候我们需要将表单元素隐藏起来,只将必要的内容展示在页面上。这时,我们可以使用 JavaScript 帮助我们实现显示/隐藏表单文字。 下面是一条实现的完整攻略: 添加 HTML 元素 为了实现显示/隐藏表单文字,我们需要使用 JavaScript 操作 HT…

    JavaScript 2023年6月10日
    00
  • 用srcElement实现添加效果 原创

    对于“用srcElement实现添加效果 原创”的完整攻略,我准备了以下讲解: 1. 什么是srcElement srcElement是javascript中一个表示事件对象(event)属性的属性,指向触发该事件的对象。通常,我们可以使用srcElement来获取触发当前事件的元素。值得注意的是,srcElement是IE浏览器独有的属性,其他浏览器可能需…

    JavaScript 2023年6月10日
    00
  • JS设置时间无效问题的解决办法

    接下来我会详细讲解JS设置时间无效问题的解决办法。 问题的描述 在前端开发中,我们经常会用到JS来设置时间,在一些特定的情况下,我们会发现JS设置的时间无效,这时候我们需要解决这个问题。 解决办法 使用UTC时间 JS设置日期和时间时,需要注意它的时区。如果你使用的是“2016/02/01 12:00”这样的日期字符串,JS会默认为你的本地时间。如果你的本地…

    JavaScript 2023年5月27日
    00
  • 理解JavaScript事件对象

    理解JavaScript事件对象在事件处理中是非常重要的。在JavaScript中,事件对象(Event Object)是事件处理函数中的第一个参数。当特定事件被触发时,浏览器会自动创建事件对象(Event Object)。开发者可以使用该对象在事件处理函数中访问事件的详细信息,例如鼠标位置,按键,以及事件类型等。 JavaScript事件对象的属性 事件对…

    JavaScript 2023年5月27日
    00
  • 使用js编写实现拼图游戏

    当你想要使用JS编写实现拼图游戏的时候,你需要遵循如下的步骤: 1. 确定游戏规则和目标 在编写拼图游戏之前,你需要确定游戏的规则和目标。例如,游戏可以是一个15方块的格子,每个方块初始位置随机分布,玩家需要通过移动方块来拼成完整的图案。游戏的目标是以最少的移动步骤完成拼图。 2. 创建HTML模板 使用html创建一个基础游戏界面,在这个游戏界面中,你需要…

    JavaScript 2023年6月10日
    00
  • Javascript RegExp global 属性

    JavaScript RegExp的global属性 JavaScript的RegExp对象中的global属性是一个布尔值,表示正则表达式是否具有全局标志g。当global属性为true时,正则表达式将匹配字符串中的所有匹配项而不仅仅是第一个匹配项。 语法 global属性的语法如下: RegExp.global 示例1:使用global属性匹配字符串中的…

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