diff --git a/components/tree/doc/index.en-US.md b/components/tree/doc/index.en-US.md index deaf34527c1..710a948e741 100644 --- a/components/tree/doc/index.en-US.md +++ b/components/tree/doc/index.en-US.md @@ -79,7 +79,7 @@ Almost anything can be represented in a tree structure. Examples include directo #### NzFormatBeforeDropEvent props -| 参数 | 说明 | 类型 | 默认值 | +| Property | Description | Type | Default | | --- | --- | --- | --- | | dragNode | Current drag node (existing when dragged) | NzTreeNode | - | | node | The current operation node (such as the target node to drop while dragging) | NzTreeNode | - | diff --git a/components/tree/nz-tree.service.ts b/components/tree/nz-tree.service.ts index 0f0cf7bfba8..013e99ca0ca 100644 --- a/components/tree/nz-tree.service.ts +++ b/components/tree/nz-tree.service.ts @@ -75,15 +75,25 @@ export class NzTreeService { */ checkTreeNodeParents(node: NzTreeNode): void { const parentNode = node.getParentNode(); + // 全禁用节点不选中 + if (parentNode && (parentNode.isDisabled || parentNode.isDisableCheckbox)) { + if (parentNode.children.every(child => child.isDisabled || child.isDisableCheckbox)) { + return; + } + } if (parentNode) { if (parentNode.children.every(child => child.isDisabled || child.isDisableCheckbox || (!child.isHalfChecked && child.isAllChecked))) { - parentNode.isChecked = true; - parentNode.isAllChecked = true; - parentNode.isHalfChecked = false; + if (!(parentNode.isDisabled || parentNode.isDisableCheckbox)) { + parentNode.isChecked = true; + parentNode.isAllChecked = true; + parentNode.isHalfChecked = false; + } } else if (parentNode.children.some(child => child.isHalfChecked || child.isAllChecked)) { - parentNode.isChecked = false; - parentNode.isAllChecked = false; - parentNode.isHalfChecked = true; + if (!(parentNode.isDisabled || parentNode.isDisableCheckbox)) { + parentNode.isChecked = false; + parentNode.isAllChecked = false; + parentNode.isHalfChecked = true; + } } else { parentNode.isChecked = false; parentNode.isAllChecked = false; @@ -254,9 +264,10 @@ export class NzTreeService { if (node.isChecked) { node.isHalfChecked = false; } - for (const n of node.children) { - this.checkTreeNodeChildren(n, value); - } + } + // 遍历全部子节点 + for (const n of node.children) { + this.checkTreeNodeChildren(n, value); } } diff --git a/components/tree/nz-tree.spec.ts b/components/tree/nz-tree.spec.ts index 772b676ed75..4532311ce0a 100644 --- a/components/tree/nz-tree.spec.ts +++ b/components/tree/nz-tree.spec.ts @@ -44,9 +44,9 @@ describe('tree component test', () => { expect(allSelectedKeys[ 1 ].getAttribute('title')).toEqual('child1.1'); expect(treeInstance.treeComponent.getSelectedNodeList().length).toEqual(2); - // checked + // checked(child1 has disabled nodes) const allCheckedKeys = treeElement.querySelectorAll('.ant-tree-checkbox-checked'); - expect(allCheckedKeys.length).toEqual(4); + expect(allCheckedKeys.length).toEqual(2); // merged to one node expect(treeInstance.treeComponent.getCheckedNodeList().length).toEqual(1); // expanded @@ -103,33 +103,41 @@ describe('tree component test', () => { const expandSpy = spyOn(treeInstance, 'onExpand'); // detect changes fixture.detectChanges(); - expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(4); + // 2 checked in default(3 disabled not be contained) + expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(2); // check child1 let targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 0 ]; expect(targetNode.classList).toContain('ant-tree-checkbox-indeterminate'); dispatchMouseEvent(targetNode, 'click'); fixture.detectChanges(); targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 0 ]; - expect(targetNode.classList).toContain('ant-tree-checkbox-checked'); - // all nodes inside root1 are checked - expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(6); - expect(checkSpy).toHaveBeenCalled(); + // all nodes inside root1 are checked(except 2 disabled) + expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(5); expect(checkSpy).toHaveBeenCalledTimes(1); // for bug test https://github.com/NG-ZORRO/ng-zorro-antd/issues/1423 // auto merge child node expect(treeInstance.treeComponent.getCheckedNodeList().length).toEqual(1); - expect(treeInstance.treeComponent.getCheckedNodeList()[0].title).toEqual('root1'); + expect(treeInstance.treeComponent.getCheckedNodeList()[ 0 ].title).toEqual('root1'); // cancel checked status dispatchMouseEvent(targetNode, 'click'); fixture.detectChanges(); + + // click node grandchild1.2.1 to test disabled node.(won't effect parent node) + targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 4 ]; + dispatchMouseEvent(targetNode, 'click'); + fixture.detectChanges(); + expect(treeInstance.treeComponent.getCheckedNodeList().length).toEqual(1); + dispatchMouseEvent(targetNode, 'click'); + fixture.detectChanges(); + expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(0); expect(treeInstance.treeComponent.getCheckedNodeList().length).toEqual(0); - // test half checked nodes, click child1.1 + // test half checked nodes, click child1.1, just root1 halfchecked(child1 is full checked) targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 2 ]; dispatchMouseEvent(targetNode, 'click'); fixture.detectChanges(); - expect(treeInstance.treeComponent.getHalfCheckedNodeList().length).toEqual(2); - // click disabled node + expect(treeInstance.treeComponent.getHalfCheckedNodeList().length).toEqual(1); + // // click disabled node targetNode = treeElement.querySelector('.ant-tree-checkbox-disabled'); dispatchMouseEvent(targetNode, 'click'); fixture.detectChanges(); @@ -164,7 +172,7 @@ describe('tree component test', () => { const searchSpy = spyOn(treeInstance, 'onSearch'); treeInstance.searchValue = 'grand'; fixture.detectChanges(); - expect(treeElement.querySelectorAll('.font-highlight').length).toEqual(3); + expect(treeElement.querySelectorAll('.font-highlight').length).toEqual(5); expect(searchSpy).toHaveBeenCalled(); expect(searchSpy).toHaveBeenCalledTimes(1); }); @@ -567,7 +575,7 @@ class NzDemoStrictTreeComponent { class NzDemoBasicTreeComponent { @ViewChild(NzTreeComponent) treeComponent: NzTreeComponent; expandKeys = [ '1001', '10001' ]; - checkedKeys = [ '10001', '100012' ]; + checkedKeys = [ '10001' ]; selectedKeys = [ '10001', '100011' ]; multiple = true; expandDefault = false; @@ -591,18 +599,18 @@ class NzDemoBasicTreeComponent { { title : 'child1.2', key : '100012', + disabled: true, children: [ { - title : 'grandchild1.2.1', - key : '1000121', - isLeaf : true, - disabled: true + title : 'grandchild1.2.1', + key : '1000121', + isLeaf: true }, { - title : 'grandchild1.2.2', - key : '1000122', - isLeaf : true, - checked: true + title : 'grandchild1.2.2', + key : '1000122', + isLeaf : true, + disableCheckbox: true } ] } @@ -621,8 +629,21 @@ class NzDemoBasicTreeComponent { { title : 'child2.1', key : '10021', - children : [], - disableCheckbox: true + disableCheckbox: true, + children : [ + { + title : 'grandchild2.1.1', + key : '100211', + isLeaf : true, + disableCheckbox: true + }, + { + title : 'grandchild2.1.2', + key : '1002112', + isLeaf : true, + disableCheckbox: true + } + ] }, { title : 'child2.2',