未选中子节点时取消选中父节点

时间:2012-07-24 05:50:58

标签: javascript extjs

我是新手extJs用户。我使用带有复选框的树面板,我想在未检查子节点时取消选中父节点。下面是我的代码,希望你能帮助我们,我不知道该怎么做。

我的treepanel的结构是这样的:

  • parentnode1
    • 子parentNode1.1
      • child1.1
      • child1.2
      • child1.3
    • subparentNode1.2
      • child2.1
      • child2.2
  • parentnode2
    • subparentNode2.1
      • child2.1.1


var treeCheck = new Ext.tree.TreePanel({
    //some code here
});

//event here

treeCheck.on('checkchange', function(node, checked) {
    if(node.hasChildNodes()==true) {

        node.eachChild(function(n) {
            n.getUI().toggleCheck(checked);
        });

    } else {

        if(!checked) {
            var _parentNode = node.parentNode;
            //i dont know what to do here...
            //specifically, i want to uncheck the parent node and subparent node
            //when the children/child node is unchecked
        }
    }
});

3 个答案:

答案 0 :(得分:5)

有同样的问题。通过添加此事件处理程序修复它:

treePanel.on('checkchange', function(node, isChecked) {

    // Propagate change downwards (for all children of current node).
    var setChildrenCheckedStatus = function (current) {
        if (current.parentNode) {
            var parent = current.parentNode;
            current.set('checked', parent.get('checked'));
        }

        if (current.hasChildNodes()) {
            current.eachChild(arguments.callee);
        }
    };
    if (node.hasChildNodes()) {
        node.eachChild(setChildrenCheckedStatus);
    }

    // Propagate change upwards (if all siblings are the same, update parent).
    var updateParentCheckedStatus = function (current) {
        if (current.parentNode) {
            var parent = current.parentNode;

            var checkedCount = 0;
            parent.eachChild(function(n) {
                checkedCount += (n.get('checked') ? 1 : 0);
            });

            // Children have same value if all of them are checked or none is checked.
            var sameValue = (checkedCount == parent.childNodes.length) || (checkedCount == 0);

            if (sameValue) {
                var checkedValue = (checkedCount == parent.childNodes.length);
                parent.set('checked', checkedValue);
            } else {
                // Not all of the children are checked, so uncheck the parent.
                parent.set('checked', false);
            }

            updateParentCheckedStatus(parent);
        }
    }
    updateParentCheckedStatus(node);
});

以递归方式向下工作(向下检查节点的所有子节点)和向上(如果取消选中节点,则取消选中父节点)。

答案 1 :(得分:0)

if(!checked)
{
    //To uncheck the child nodes (I think you didn't ask this)
    /*for(var i in node.childNodes)
        node.childNodes[i].set('checked', false);
    */
    //To unchek the parent node
    node.parentNode.set('checked', false);
    node.parentNode.parentNode.set('checked', false);
}

注意:我测试了它,发现它不是递归的。

node.parentNode.set('checked', false)开始,它应该取消选中祖母。

答案 2 :(得分:0)

为了完整性,对于这种递归,ExtJS 3.4分别有Ext.tree.Node方法级联和冒泡。

        listeners: {
        'checkchange': function(node, checked){

                var checkChange = function(currentNode, flag) {
                    try{
                        currentNode.attributes.checked  = flag;
                        currentNode.ui.checkbox.checked = flag;
                    }
                    catch(e){
                        // just avoiding error when node has no such attribute
                    }
                };

                /**
                 * Cascades down the tree from this node propagating the 'checkChange' event.
                 */
                 node.cascade(function() {
                    if(this.expanded === false){
                        this.expand(true);
                    }

                    checkChange(this, checked);

                    return true;
                });

                /**
                 * Bubbles up the tree from this node changing parent's state depending on children.
                 */
                node.bubble(function() {
                    if(this.hasChildNodes()){

                        var checkedCount = 0;

                        this.eachChild(function(child) {
                            checkedCount += (child.attributes.checked ? 1 : 0);
                        });

                        var checkedValue = (checkedCount == this.childNodes.length) && checkedCount !== 0;

                        checkChange(this, checkedValue);
                    }
                });
         }
     },

可以找到一个功能齐全的小提琴here

Obs:泡沫的逻辑来自 ag0rex