diff --git a/components/ng-zorro-antd.module.ts b/components/ng-zorro-antd.module.ts
index 1dfc0261bcc..a51a87408af 100644
--- a/components/ng-zorro-antd.module.ts
+++ b/components/ng-zorro-antd.module.ts
@@ -14,6 +14,7 @@ import { NzCarouselModule } from './carousel/nz-carousel.module';
import { NzCascaderModule } from './cascader/nz-cascader.module';
import { NzCheckboxModule } from './checkbox/nz-checkbox.module';
import { NzCollapseModule } from './collapse/nz-collapse.module';
+import { NzWaveModule } from './core/wave/nz-wave.module';
import { NzDatePickerModule } from './date-picker/date-picker.module';
import { NzDividerModule } from './divider/nz-divider.module';
import { NzDrawerModule } from './drawer/nz-drawer.module';
@@ -30,6 +31,7 @@ import { NzMenuModule } from './menu/nz-menu.module';
import { NzMessageModule } from './message/nz-message.module';
import { NzModalModule } from './modal/nz-modal.module';
import { NzNotificationModule } from './notification/nz-notification.module';
+import { NzTreeSelectModule } from './tree-select/nz-tree-select.module';
import { NzPaginationModule } from './pagination/nz-pagination.module';
import { NzPopconfirmModule } from './popconfirm/nz-popconfirm.module';
import { NzPopoverModule } from './popover/nz-popover.module';
@@ -49,10 +51,8 @@ import { NzTimePickerModule } from './time-picker/nz-time-picker.module';
import { NzTimelineModule } from './timeline/nz-timeline.module';
import { NzToolTipModule } from './tooltip/nz-tooltip.module';
import { NzTransferModule } from './transfer/nz-transfer.module';
-import { NzTreeSelectModule } from './tree-select/nz-tree-select.module';
import { NzTreeModule } from './tree/nz-tree.module';
import { NzUploadModule } from './upload/nz-upload.module';
-import { NzWaveModule } from './core/wave/nz-wave.module';
export * from './affix';
export * from './alert';
diff --git a/components/tree-select/demo/async.ts b/components/tree-select/demo/async.ts
index 374132cb383..b46c8277a54 100755
--- a/components/tree-select/demo/async.ts
+++ b/components/tree-select/demo/async.ts
@@ -5,80 +5,39 @@ import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
selector: 'nz-demo-tree-select-async',
template: `
+ nzPlaceHolder="Please select"
+ [nzDefaultExpandedKeys]="expandKeys"
+ [nzDropdownMatchSelectWidth]="true"
+ [nzDropdownStyle]="{ 'max-height': '300px' }"
+ [(ngModel)]="value"
+ [nzNodes]="nodes"
+ [nzAsyncData]="true"
+ (nzExpandChange)="onExpandChange($event)">
`
})
export class NzDemoTreeSelectAsyncComponent implements OnInit {
- expandKeys = [ '1001', '10001' ];
+ expandKeys = [ '0-0' ];
value: string;
- nodes = [
- new NzTreeNode({
- title: 'root1',
- key: '1001',
- children: [
- {
- title: 'child1',
- key: '10001',
- children: [
- {
- title: 'child1.1',
- key: '100011',
- children: []
- },
- {
- title: 'child1.2',
- key: '100012',
- children: [
- {
- title: 'grandchild1.2.1',
- key: '1000121',
- isLeaf: true,
- disabled: true
- },
- {
- title: 'grandchild1.2.2',
- key: '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- }
- ]
- }),
- new NzTreeNode({
- title: 'root2',
- key: '1002',
- children: [
- {
- title: 'child2.1',
- key: '10021',
- children: [],
- disabled: true
- },
- {
- title: 'child2.2',
- key: '10022',
- children: [
- {
- title: 'grandchild2.2.1',
- key: '100221',
- isLeaf: true
- }
- ]
- }
- ]
- })
- ];
+ nodes = [ {
+ title : 'Node1',
+ value : '0-0',
+ key : '0-0',
+ children: [ {
+ title: 'Child Node1',
+ value: '0-0-1',
+ key : '0-0-1'
+ }, {
+ title: 'Child Node2',
+ value: '0-0-2',
+ key : '0-0-2'
+ } ]
+ }, {
+ title: 'Node2',
+ value: '0-1',
+ key : '0-1'
+ } ];
onExpandChange(e: NzFormatEmitEvent): void {
if (e.node.getChildren().length === 0 && e.node.isExpanded) {
@@ -91,39 +50,8 @@ export class NzDemoTreeSelectAsyncComponent implements OnInit {
loadNode(): Promise {
return new Promise(resolve => {
setTimeout(() => resolve([
- new NzTreeNode({
- title: 'root2',
- key: '10030-' + (new Date()).getTime(),
- children: [
- {
- title: 'child2.1',
- key: '10021',
- children: [],
- checked: true,
- disabled: true
- },
- {
- title: 'child2.2',
- key: '10022',
- children: [
- {
- title: 'grandchild2.2.1',
- key: '100221',
- isLeaf: true
- }
- ]
- }
- ]
- }),
- {
- title: 'childAdd-1',
- key: '10031-' + (new Date()).getTime()
- },
- {
- title: 'childAdd-2',
- key: '10032-' + (new Date()).getTime(),
- isLeaf: true
- }]),
+ { title: 'Child Node', key: `${(new Date()).getTime()}-0` },
+ { title: 'Child Node', key: `${(new Date()).getTime()}-1` } ]),
1000);
});
}
diff --git a/components/tree-select/demo/basic.ts b/components/tree-select/demo/basic.ts
index 2ce5b5d6a50..b6a7ef5518c 100755
--- a/components/tree-select/demo/basic.ts
+++ b/components/tree-select/demo/basic.ts
@@ -16,76 +16,35 @@ import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
})
export class NzDemoTreeSelectBasicComponent implements OnInit {
- expandKeys = [ '1001', '10001' ];
+ expandKeys = [ '100', '1001' ];
value: string;
- nodes = [
- new NzTreeNode({
- title: 'root1',
- key: '1001',
+ nodes = [ {
+ title : 'parent 1',
+ key : '100',
+ children: [ {
+ title : 'parent 1-0',
+ key : '1001',
children: [
- {
- title: 'child1',
- key: '10001',
- children: [
- {
- title: 'child1.1',
- key: '100011',
- children: []
- },
- {
- title: 'child1.2',
- key: '100012',
- children: [
- {
- title: 'grandchild1.2.1',
- key: '1000121',
- isLeaf: true,
- disabled: true
- },
- {
- title: 'grandchild1.2.2',
- key: '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- }
+ { title: 'leaf 1-0-0', key: '10010', isLeaf: true },
+ { title: 'leaf 1-0-1', key: '10011', isLeaf: true }
]
- }),
- new NzTreeNode({
- title: 'root2',
- key: '1002',
+ }, {
+ title : 'parent 1-1',
+ key : '1002',
children: [
- {
- title: 'child2.1',
- key: '10021',
- children: [],
- disableCheckbox: true
- },
- {
- title: 'child2.2',
- key: '10022',
- children: [
- {
- title: 'grandchild2.2.1',
- key: '100221',
- isLeaf: true
- }
- ]
- }
+ { title: 'leaf 1-1-0', key: '10020', isLeaf: true }
]
- })
- ];
+ } ]
+ } ];
- onChange($event: NzTreeNode): void {
+ onChange($event: string): void {
console.log($event);
}
ngOnInit(): void {
// mock async
setTimeout(() => {
- this.value = '10001';
+ this.value = '1001';
}, 1000);
}
}
diff --git a/components/tree-select/demo/checkable.ts b/components/tree-select/demo/checkable.ts
index ef4b2f30b72..4fbb8472a1e 100755
--- a/components/tree-select/demo/checkable.ts
+++ b/components/tree-select/demo/checkable.ts
@@ -17,68 +17,40 @@ import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
export class NzDemoTreeSelectCheckableComponent implements OnInit {
- value: string[] = [ '10001', '10022' ];
- nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
- children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- children: []
- },
- {
- title : 'child1.2',
- key : '100012',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf : true,
- disabled: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- }
- ]
- }),
- new NzTreeNode({
- title : 'root2',
- key : '1002',
- children: [
- {
- title : 'child2.1',
- key : '10021',
- children : [],
- disableCheckbox: true
- },
- {
- title : 'child2.2',
- key : '10022',
- children: [
- {
- title : 'grandchild2.2.1',
- key : '100221',
- isLeaf: true
- }
- ]
- }
- ]
- })
- ];
+ value: string[] = [ '0-0-0' ];
+ nodes = [ {
+ title : 'Node1',
+ value : '0-0',
+ key : '0-0',
+ children: [ {
+ title : 'Child Node1',
+ value : '0-0-0',
+ key : '0-0-0',
+ isLeaf: true
+ } ]
+ }, {
+ title : 'Node2',
+ value : '0-1',
+ key : '0-1',
+ children: [ {
+ title : 'Child Node3',
+ value : '0-1-0',
+ key : '0-1-0',
+ isLeaf: true
+ }, {
+ title : 'Child Node4',
+ value : '0-1-1',
+ key : '0-1-1',
+ isLeaf: true
+ }, {
+ title : 'Child Node5',
+ value : '0-1-2',
+ key : '0-1-2',
+ isLeaf: true
+ } ]
+ } ];
- onChange($event: NzTreeNode): void {
+ onChange($event: string[]): void {
console.log($event);
}
diff --git a/components/tree-select/demo/multiple.ts b/components/tree-select/demo/multiple.ts
index 5ec4524bc8a..4cda4262f52 100755
--- a/components/tree-select/demo/multiple.ts
+++ b/components/tree-select/demo/multiple.ts
@@ -1,85 +1,44 @@
-import {Component, OnInit} from '@angular/core';
-import {NzFormatEmitEvent, NzTreeNode} from 'ng-zorro-antd';
+import { Component, OnInit } from '@angular/core';
+import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
@Component({
selector: 'nz-demo-tree-select-multiple',
template: `
+ [nzNodes]="nodes"
+ [nzDefaultExpandAll]="true"
+ [nzAllowClear]="false"
+ nzPlaceHolder="Please select"
+ [(ngModel)]="value"
+ [nzMultiple]="true"
+ (ngModelChange)="onChange($event)">
`
})
export class NzDemoTreeSelectMultipleComponent implements OnInit {
- value: string[] = ['100011'];
- nodes = [
- new NzTreeNode({
- title: 'root1',
- key: '1001',
+ value: string[] = [];
+ nodes = [ {
+ title : 'parent 1',
+ key : '100',
+ children: [ {
+ title : 'parent 1-0',
+ key : '1001',
children: [
- {
- title: 'child1',
- key: '10001',
- children: [
- {
- title: 'child1.1',
- key: '100011',
- children: []
- },
- {
- title: 'child1.2',
- key: '100012',
- children: [
- {
- title: 'grandchild1.2.1',
- key: '1000121',
- isLeaf: true,
- disabled: true
- },
- {
- title: 'grandchild1.2.2',
- key: '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- }
+ { title: 'leaf 1-0-0', key: '10010', isLeaf: true },
+ { title: 'leaf 1-0-1', key: '10011', isLeaf: true }
]
- }),
- new NzTreeNode({
- title: 'root2',
- key: '1002',
+ }, {
+ title : 'parent 1-1',
+ key : '1002',
children: [
- {
- title: 'child2.1',
- key: '10021',
- children: [],
- disableCheckbox: true
- },
- {
- title: 'child2.2',
- key: '10022',
- children: [
- {
- title: 'grandchild2.2.1',
- key: '100221',
- isLeaf: true
- }
- ]
- }
+ { title: 'leaf 1-1-0', key: '10020', isLeaf: true }
]
- })
- ];
+ } ]
+ } ];
- onChange($event: NzTreeNode): void {
+ onChange($event: string[]): void {
console.log($event);
}
diff --git a/components/tree-select/nz-tree-select.component.html b/components/tree-select/nz-tree-select.component.html
index 41efc401ed7..d13dff7ad00 100644
--- a/components/tree-select/nz-tree-select.component.html
+++ b/components/tree-select/nz-tree-select.component.html
@@ -16,21 +16,20 @@
[ngStyle]="nzDropdownStyle">
+ (nzCheckBoxChange)="nzTreeCheckBoxChange.emit($event)">
diff --git a/components/tree-select/nz-tree-select.component.ts b/components/tree-select/nz-tree-select.component.ts
index 536b9bd2b71..cc5c84e8dfb 100644
--- a/components/tree-select/nz-tree-select.component.ts
+++ b/components/tree-select/nz-tree-select.component.ts
@@ -40,7 +40,7 @@ import { filter, tap } from 'rxjs/operators';
import { selectDropDownAnimation } from '../core/animation/select-dropdown-animations';
import { selectTagAnimation } from '../core/animation/select-tag-animations';
import { InputBoolean } from '../core/util/convert';
-import { NzFormatEmitEvent } from '../tree/interface';
+import { NzFormatEmitEvent } from '../tree';
import { NzTreeNode } from '../tree/nz-tree-node';
import { NzTreeComponent } from '../tree/nz-tree.component';
@@ -243,7 +243,7 @@ export class NzTreeSelectComponent implements ControlValueAccessor, OnInit, Afte
node.isSelected = false;
node.isChecked = false;
if (this.nzCheckable) {
- this.treeRef.nzTreeService.checkTreeNode(node);
+ this.treeRef.nzTreeService.conduct(node);
this.treeRef.nzTreeService.setCheckedNodeList(node);
} else {
this.treeRef.nzTreeService.setSelectedNodeList(node, this.nzMultiple);
@@ -306,7 +306,7 @@ export class NzTreeSelectComponent implements ControlValueAccessor, OnInit, Afte
const node = event.node;
if (this.nzCheckable && !node.isDisabled && !node.isDisableCheckbox) {
node.isChecked = !node.isChecked;
- this.treeRef.nzTreeService.checkTreeNode(node);
+ this.treeRef.nzTreeService.conduct(node);
this.treeRef.nzTreeService.setCheckedNodeList(node);
}
if (this.nzCheckable) {
@@ -367,8 +367,8 @@ export class NzTreeSelectComponent implements ControlValueAccessor, OnInit, Afte
}
updateDropDownClassMap(): void {
- if (this.treeRef && !this.treeRef.classMap[ 'ant-select-tree' ]) {
- this.treeRef.classMap = { ...this.treeRef.classMap, [ 'ant-select-tree' ]: true };
+ if (this.treeRef && !this.treeRef.nzTreeClass[ 'ant-select-tree' ]) {
+ this.treeRef.nzTreeClass = { ...this.treeRef.nzTreeClass, [ 'ant-select-tree' ]: true };
}
this.dropDownClassMap = {
[ 'ant-select-dropdown' ] : true,
diff --git a/components/tree-select/nz-tree-select.spec.ts b/components/tree-select/nz-tree-select.spec.ts
index 6800b1ae021..891d3647df4 100644
--- a/components/tree-select/nz-tree-select.spec.ts
+++ b/components/tree-select/nz-tree-select.spec.ts
@@ -1,6 +1,6 @@
import { BACKSPACE } from '@angular/cdk/keycodes';
import { OverlayContainer } from '@angular/cdk/overlay';
-import { ChangeDetectionStrategy, Component, ViewChild } from '@angular/core';
+import { Component, ViewChild } from '@angular/core';
import { async, fakeAsync, flush, inject, tick, TestBed } from '@angular/core/testing';
import { FormsModule, FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
@@ -22,7 +22,7 @@ describe('tree-select component', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports : [ NzTreeSelectModule, NoopAnimationsModule, FormsModule, ReactiveFormsModule ],
- declarations: [ NzTestTreeSelectBasicComponent, NzTestTreeSelectCheckableComponent, NzTestTreeSelectFormComponent, NzTestTreeSelectAsyncNodesComponent, NzTestTreeSelectOnPushComponent ]
+ declarations: [ NzTestTreeSelectBasicComponent, NzTestTreeSelectCheckableComponent, NzTestTreeSelectFormComponent ]
});
TestBed.compileComponents();
inject([ OverlayContainer ], (oc: OverlayContainer) => {
@@ -35,38 +35,6 @@ describe('tree-select component', () => {
overlayContainer.ngOnDestroy();
}));
- describe('OnPush', () => {
- let fixture;
- let testComponent: NzTestTreeSelectOnPushComponent;
- let treeSelectComponent: NzTreeSelectComponent;
- let treeSelect;
-
- beforeEach(fakeAsync(() => {
- fixture = TestBed.createComponent(NzTestTreeSelectOnPushComponent);
- fixture.detectChanges();
- testComponent = fixture.debugElement.componentInstance;
- treeSelect = fixture.debugElement.query(By.directive(NzTreeSelectComponent));
- treeSelectComponent = treeSelect.componentInstance;
- fixture.detectChanges();
- flush();
- tick(200);
- fixture.detectChanges();
- }));
-
- it('should close when the outside clicks', fakeAsync(() => {
- treeSelect.nativeElement.click();
- fixture.detectChanges();
- expect(treeSelectComponent.nzOpen).toBe(true);
- tick(200);
- expect((overlayContainerElement.querySelector('.ant-select-dropdown') as HTMLElement).style.opacity).toBe('1');
- dispatchFakeEvent(overlayContainerElement.querySelector('.cdk-overlay-backdrop'), 'click');
- fixture.detectChanges();
- tick();
- expect(treeSelectComponent.nzOpen).toBe(false);
- expect((overlayContainerElement.querySelector('.ant-select-dropdown') as HTMLElement).style.opacity).toBe('0');
- }));
- });
-
describe('basic', () => {
let fixture;
let testComponent: NzTestTreeSelectBasicComponent;
@@ -81,18 +49,19 @@ describe('tree-select component', () => {
treeSelectComponent = treeSelect.componentInstance;
fixture.detectChanges();
flush();
+ fixture.detectChanges();
tick(200);
fixture.detectChanges();
}));
- it('should size work', () => {
+ it('should size work', fakeAsync(() => {
testComponent.size = 'small';
fixture.detectChanges();
expect(treeSelect.nativeElement.classList).toContain('ant-select-sm');
testComponent.size = 'large';
fixture.detectChanges();
expect(treeSelect.nativeElement.classList).toContain('ant-select-lg');
- });
+ }));
it('should allowClear work', () => {
expect(treeSelect.nativeElement.classList).not.toContain('ant-select-allow-clear');
testComponent.allowClear = true;
@@ -164,13 +133,17 @@ describe('tree-select component', () => {
it('should set null value work', fakeAsync(() => {
fixture.detectChanges();
expect(testComponent.value).toBe('10001');
+ testComponent.nzSelectTreeComponent.updateSelectedNodes();
+ fixture.detectChanges();
testComponent.setNull();
fixture.detectChanges();
- tick(200);
+ tick();
+ fixture.detectChanges();
+ tick();
fixture.detectChanges();
expect(testComponent.value).toBe(null);
- expect(treeSelectComponent.selectedNodes.length).toBe(0);
- expect(treeSelectComponent.value.length).toBe(0);
+ expect(testComponent.nzSelectTreeComponent.selectedNodes.length).toEqual(0);
+ expect(testComponent.nzSelectTreeComponent.value.length).toBe(0);
}));
it('should dropdown style work', fakeAsync(() => {
treeSelect.nativeElement.click();
@@ -185,7 +158,7 @@ describe('tree-select component', () => {
fixture.detectChanges();
expect(treeSelectComponent.nzOpen).toBe(true);
fixture.detectChanges();
- const targetNode = overlayContainerElement.querySelectorAll('li')[ 2 ];
+ const targetNode = overlayContainerElement.querySelectorAll('nz-tree-node')[ 2 ];
dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
flush();
@@ -243,6 +216,7 @@ describe('tree-select component', () => {
treeSelectComponent = treeSelect.componentInstance;
fixture.detectChanges();
flush();
+ fixture.detectChanges();
tick(200);
fixture.detectChanges();
}));
@@ -282,15 +256,15 @@ describe('tree-select component', () => {
it('should set null value work', fakeAsync(() => {
fixture.detectChanges();
expect(testComponent.value[ 0 ]).toBe('1000122');
- treeSelectComponent.updateSelectedNodes();
- fixture.detectChanges();
testComponent.setNull();
fixture.detectChanges();
- tick(200);
+ tick();
+ fixture.detectChanges();
+ tick();
fixture.detectChanges();
expect(testComponent.value).toBe(null);
- expect(treeSelectComponent.selectedNodes.length).toBe(0);
- expect(treeSelectComponent.value.length).toBe(0);
+ expect(testComponent.nzSelectTreeComponent.selectedNodes.length).toBe(0);
+ expect(testComponent.nzSelectTreeComponent.value.length).toBe(0);
}));
it('should remove checked when press backs', fakeAsync(() => {
@@ -319,7 +293,7 @@ describe('tree-select component', () => {
fixture.detectChanges();
expect(treeSelectComponent.nzOpen).toBe(true);
fixture.detectChanges();
- const targetNode = overlayContainerElement.querySelectorAll('li')[ 2 ];
+ const targetNode = overlayContainerElement.querySelectorAll('nz-tree-node')[ 2 ];
dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
flush();
@@ -366,38 +340,6 @@ describe('tree-select component', () => {
}));
});
- describe('async nodes', () => {
- let fixture;
- let testComponent;
- let treeSelect;
- let treeSelectComponent: NzTreeSelectComponent;
- beforeEach(fakeAsync(() => {
- fixture = TestBed.createComponent(NzTestTreeSelectAsyncNodesComponent);
- fixture.detectChanges();
- testComponent = fixture.debugElement.componentInstance;
- treeSelect = fixture.debugElement.query(By.directive(NzTreeSelectComponent));
- treeSelectComponent = treeSelect.componentInstance;
- fixture.detectChanges();
- flush();
- tick(200);
- fixture.detectChanges();
- }));
- it('should update selected nodes after load nodes', fakeAsync(() => {
- treeSelectComponent.updateSelectedNodes();
- fixture.detectChanges();
- expect(treeSelectComponent.selectedNodes.length).toBe(0);
- testComponent.loadNodes();
- tick(200);
- fixture.detectChanges();
- flush();
- fixture.detectChanges();
- treeSelectComponent.updateSelectedNodes();
- fixture.detectChanges();
- expect(treeSelectComponent.selectedNodes.length).toBe(1);
- }));
-
- });
-
});
@Component({
@@ -621,107 +563,3 @@ export class NzTestTreeSelectFormComponent {
this.formGroup.get('select').reset(null);
}
}
-
-@Component({
- selector: 'nz-test-tree-select-async-nodes',
- template: `
-
-
- `
-})
-
-export class NzTestTreeSelectAsyncNodesComponent {
- value: string = '10001';
- nodes = [];
-
- loadNodes(): void {
- setTimeout(() => {
- this.nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
- children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- children: []
- },
- {
- title : 'child1.2',
- key : '100012',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf : true,
- disabled: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- }
- ]
- }),
- new NzTreeNode({
- title : 'root2',
- key : '1002',
- children: [
- {
- title : 'child2.1',
- key : '10021',
- children : [],
- disableCheckbox: true
- },
- {
- title : 'child2.2',
- key : '10022',
- children: [
- {
- title : 'grandchild2.2.1',
- key : '100221',
- isLeaf: true
- }
- ]
- }
- ]
- })
- ];
- });
- }
-}
-
-@Component({
- selector: 'nz-test-tree-select-on-push',
- template: `
-
-
- `,
- changeDetection: ChangeDetectionStrategy.OnPush
-})
-
-export class NzTestTreeSelectOnPushComponent {
- value: string = '1001';
- nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001'
- }),
- new NzTreeNode({
- title : 'root2',
- key : '1002'
- })
- ];
-}
diff --git a/components/tree/demo/basic-controlled.md b/components/tree/demo/basic-controlled.md
new file mode 100644
index 00000000000..d85dd9116db
--- /dev/null
+++ b/components/tree/demo/basic-controlled.md
@@ -0,0 +1,14 @@
+---
+order: 1
+title:
+ zh-CN: 受控操作示例
+ en-US: basic controlled example
+---
+
+## zh-CN
+
+受控操作示例(默认)。
+
+## en-US
+
+basic controlled example.
diff --git a/components/tree/demo/basic-controlled.ts b/components/tree/demo/basic-controlled.ts
new file mode 100644
index 00000000000..c3e73357bd9
--- /dev/null
+++ b/components/tree/demo/basic-controlled.ts
@@ -0,0 +1,71 @@
+import { Component, OnInit } from '@angular/core';
+import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
+
+@Component({
+ selector: 'nz-demo-tree-basic-controlled',
+ template: `
+
+
+ `
+})
+
+export class NzDemoTreeBasicControlledComponent implements OnInit {
+ defaultCheckedKeys = [ '0-0-0' ];
+ defaultSelectedKeys = [];
+ defaultExpandedKeys = [ '0-0', '0-0-0', '0-0-1' ];
+
+ nodes = [ {
+ title : '0-0',
+ key : '0-0',
+ expanded: true,
+ children: [ {
+ title : '0-0-0',
+ key : '0-0-0',
+ children: [
+ { title: '0-0-0-0', key: '0-0-0-0', isLeaf: true },
+ { title: '0-0-0-1', key: '0-0-0-1', isLeaf: true },
+ { title: '0-0-0-2', key: '0-0-0-2', isLeaf: true }
+ ]
+ }, {
+ title : '0-0-1',
+ key : '0-0-1',
+ children: [
+ { title: '0-0-1-0', key: '0-0-1-0', isLeaf: true },
+ { title: '0-0-1-1', key: '0-0-1-1', isLeaf: true },
+ { title: '0-0-1-2', key: '0-0-1-2', isLeaf: true }
+ ]
+ }, {
+ title : '0-0-2',
+ key : '0-0-2',
+ isLeaf: true
+ } ]
+ }, {
+ title : '0-1',
+ key : '0-1',
+ children: [
+ { title: '0-1-0-0', key: '0-1-0-0', isLeaf: true },
+ { title: '0-1-0-1', key: '0-1-0-1', isLeaf: true },
+ { title: '0-1-0-2', key: '0-1-0-2', isLeaf: true }
+ ]
+ }, {
+ title : '0-2',
+ key : '0-2',
+ isLeaf: true
+ } ];
+
+ nzEvent(event: NzFormatEmitEvent): void {
+ console.log(event);
+ }
+
+ ngOnInit(): void {
+ }
+}
diff --git a/components/tree/demo/basic.md b/components/tree/demo/basic.md
index e78d61e15c1..ec62aa3535d 100644
--- a/components/tree/demo/basic.md
+++ b/components/tree/demo/basic.md
@@ -12,8 +12,3 @@ title:
## en-US
The most basic usage, tell you how to use checkable, selectable, disabled, defaultExpandKeys, and etc.
-
-
-
diff --git a/components/tree/demo/basic.ts b/components/tree/demo/basic.ts
index d492b9d89be..c4848a07636 100644
--- a/components/tree/demo/basic.ts
+++ b/components/tree/demo/basic.ts
@@ -1,74 +1,61 @@
-import { Component, OnInit } from '@angular/core';
-import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { NzFormatEmitEvent, NzTreeNode, NzTreeNodeOptions } from 'ng-zorro-antd';
@Component({
selector: 'nz-demo-tree-basic',
template: `
- `
+ #treeCom
+ [nzData]="nodes"
+ nzCheckable="true"
+ nzMultiple="true"
+ [nzCheckedKeys]="defaultCheckedKeys"
+ [nzExpandedKeys]="defaultExpandedKeys"
+ [nzSelectedKeys]="defaultSelectedKeys"
+ (nzClick)="nzClick($event)"
+ (nzCheckBoxChange)="nzCheck($event)">
+
+ `
})
export class NzDemoTreeBasicComponent implements OnInit {
- expandKeys = [ '1001', '10001' ];
- checkedKeys = [ '100011', '1002' ];
- selectedKeys = [ '10001', '100011' ];
- expandDefault = false;
- nodes = [
- new NzTreeNode({
- title : 'root1',
+ @ViewChild('treeCom') treeCom;
+ defaultCheckedKeys = [ '1001', '1002' ];
+ defaultSelectedKeys = [ '10011' ];
+ defaultExpandedKeys = [ '100', '1001' ];
+
+ nodes: NzTreeNodeOptions[] = [ {
+ title : 'parent 1',
+ key : '100',
+ children: [ {
+ title : 'parent 1-0',
key : '1001',
+ disabled: true,
+ children: [
+ { title: 'leaf 1-0-0', key: '10010', disableCheckbox: true, isLeaf: true },
+ { title: 'leaf 1-0-1', key: '10011', isLeaf: true, checked: true }
+ ]
+ }, {
+ title : 'parent 1-1',
+ key : '1002',
children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- isLeaf: true
- },
- {
- title : 'child1.2',
- key : '100012',
- isLeaf: true
- }
- ]
- },
- {
- title : 'child2',
- key : '10002',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf : true,
- disabled: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf: true
- }
- ]
- }
+ { title: 'leaf 1-1-0', key: '10020', isLeaf: true }
]
- })
- ];
+ } ]
+ } ];
- mouseAction(name: string, event: NzFormatEmitEvent): void {
- console.log(name, event);
+ nzClick(event: NzFormatEmitEvent): void {
+ console.log(event, event.selectedKeys, event.keys, event.nodes);
+ }
+
+ nzCheck(event: NzFormatEmitEvent): void {
+ console.log(event, event.checkedKeys, event.keys, event.nodes);
}
ngOnInit(): void {
+ setTimeout(() => {
+ console.log(this.treeCom.nzTreeService, this.treeCom.getCheckedNodeList());
+ }, 500);
+
}
}
diff --git a/components/tree/demo/customized-icon.md b/components/tree/demo/customized-icon.md
index 96d29a43b48..3b7b6385a2c 100644
--- a/components/tree/demo/customized-icon.md
+++ b/components/tree/demo/customized-icon.md
@@ -1,15 +1,14 @@
---
-order: 4
-debug: true
+order: 7
title:
zh-CN: 自定义图标
- en-US: customize
+ en-US: Customize Icon
---
## zh-CN
-可以针对不同节点采用样式覆盖的方式定制图标,双击展开。
+可以针对不同的节点定制图标。
## en-US
-You can customize icons for different nodes by styles override and expand the node using dblclick.
+You can customize icons for different nodes.
diff --git a/components/tree/demo/customized-icon.ts b/components/tree/demo/customized-icon.ts
index f5e5c2d3e37..94c092c1e45 100644
--- a/components/tree/demo/customized-icon.ts
+++ b/components/tree/demo/customized-icon.ts
@@ -1,102 +1,30 @@
import { Component, OnInit } from '@angular/core';
-import { NzTreeNode } from 'ng-zorro-antd';
+import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
@Component({
selector: 'nz-demo-tree-customized-icon',
template: `
-
-
-
-
-
- {{node.title}}
-
-
-
- `,
- styles : [ `
- :host ::ng-deep .ant-tree {
- overflow: hidden;
- margin: 0 -24px;
- padding: 0 24px;
- }
-
- .custom-node {
- cursor: pointer;
- line-height: 30px;
- display: inline-block;
- margin: 0 -1000px;
- padding: 0 1000px;
- }
-
- .active {
- background: #1890ff;
- color: #fff;
- }
-
- .anticon {
- padding: 0 4px;
- }
- ` ]
+
+
+ `
})
+
export class NzDemoTreeCustomizedIconComponent implements OnInit {
nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
+ {
+ title : 'parent 1',
+ key : '100',
expanded: true,
+ icon : 'anticon anticon-smile-o',
children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- selected: true,
- children: []
- },
- {
- title : 'child1.2',
- key : '100012',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf : true,
- checked : true,
- disabled: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- }
+ { title: 'leaf', key: '1001', icon: 'anticon anticon-meh-o', isLeaf: true },
+ { title: 'leaf', key: '1002', icon: 'anticon anticon-frown-o', isLeaf: true }
]
- })
- ];
-
- mouseAction(name: string, e: any): void {
- switch (name) {
- case 'click':
- break;
- case 'dblclick':
- setTimeout(() => {
- e.node.isExpanded = !e.node.isExpanded;
- });
- break;
}
- }
+ ];
ngOnInit(): void {
-
}
}
diff --git a/components/tree/demo/dir-tree.md b/components/tree/demo/dir-tree.md
deleted file mode 100644
index 55b54c15feb..00000000000
--- a/components/tree/demo/dir-tree.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-order: 5
-title:
- zh-CN: 文件树
- en-US: directory tree
----
-
-## zh-CN
-
-自定义Tree组件实现文件树,点击图标展开文件夹,鼠标拖拽。右键自定义菜单。
-
-## en-US
-
-Built-in directory tree with tree component, click icon to open the folder and dnd.Trigger dropdown with contextmenu.
\ No newline at end of file
diff --git a/components/tree/demo/dir-tree.ts b/components/tree/demo/dir-tree.ts
deleted file mode 100644
index 43b728aedd7..00000000000
--- a/components/tree/demo/dir-tree.ts
+++ /dev/null
@@ -1,228 +0,0 @@
-import { Component, HostListener, OnInit, TemplateRef } from '@angular/core';
-import { NzDropdownService, NzFormatEmitEvent, NzTreeNode, NzDropdownContextComponent } from 'ng-zorro-antd';
-
-@Component({
- selector: 'nz-demo-tree-dir-tree',
- template: `
-
-
-
-
-
-
-
-
-
- {{node.title}}
- {{node?.origin?.author | lowercase}} created at 2018-04-01
-
-
-
- {{node.title}}
- {{node?.origin?.author | lowercase}} modified at 2018-05-01
-
-
-
- `,
- styles : [ `
- :host ::ng-deep .ant-tree {
- overflow: hidden;
- margin: 0 -24px;
- padding: 0 24px;
- }
-
- :host ::ng-deep .ant-tree li {
- padding: 4px 0 0 0;
- }
-
- @keyframes shine {
- 0% {
- opacity: 1;
- }
- 50% {
- opacity: 0.5;
- }
- 100% {
- opacity: 1;
- }
- }
-
- .shine-animate {
- animation: shine 2s ease infinite;
- }
-
- .custom-node {
- cursor: pointer;
- line-height: 26px;
- margin-left: 4px;
- display: inline-block;
- margin: 0 -1000px;
- padding: 0 1000px;
- }
-
- .active {
- background: #1890FF;
- color: #fff;
- }
-
- .is-dragging {
- background-color: transparent !important;
- color: #000;
- opacity: 0.7;
- }
-
- .file-name, .folder-name, .file-desc, .folder-desc {
- margin-left: 4px;
- }
-
- .file-desc, .folder-desc {
- padding: 2px 8px;
- background: #87CEFF;
- color: #FFFFFF;
- }
- ` ]
-})
-export class NzDemoTreeDirTreeComponent implements OnInit {
- dropdown: NzDropdownContextComponent;
- // can active only one node
- activedNode: NzTreeNode;
- dragNodeElement;
- nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
- author : 'ANGULAR',
- expanded: true,
- children: [
- {
- title : 'child1',
- key : '10001',
- author : 'ZORRO',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- author : 'ZORRO',
- children: []
- },
- {
- title : 'child1.2',
- key : '100012',
- author : 'ZORRO',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- author : 'ZORRO-FANS',
- isLeaf : true,
- checked : true,
- disabled: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- author: 'ZORRO-FANS',
- isLeaf: true
- }
- ]
- }
- ]
- }
- ]
- })
- ];
-
- @HostListener('mouseleave', [ '$event' ])
- mouseLeave(event: MouseEvent): void {
- event.preventDefault();
- if (this.dragNodeElement && this.dragNodeElement.className.indexOf('is-dragging') > -1) {
- this.dragNodeElement.className = this.dragNodeElement.className.replace(' is-dragging', '');
- }
- }
-
- @HostListener('mousedown')
- mouseDown(): void {
- // do not prevent
- if (this.dragNodeElement && this.dragNodeElement.className.indexOf('is-dragging') > -1) {
- this.dragNodeElement.className = this.dragNodeElement.className.replace(' is-dragging', '');
- }
- }
-
- /**
- * important:
- * if u want to custom event/node properties, u need to maintain the selectedNodesList/checkedNodesList yourself
- * @param {} data
- */
- openFolder(data: NzTreeNode | NzFormatEmitEvent): void {
- // do something if u want
- if (data instanceof NzTreeNode) {
- // change node's expand status
- if (!data.isExpanded) {
- // close to open
- data.origin.isLoading = true;
- setTimeout(() => {
- data.isExpanded = !data.isExpanded;
- data.origin.isLoading = false;
- }, 500);
- } else {
- data.isExpanded = !data.isExpanded;
- }
- } else {
- // change node's expand status
- if (!data.node.isExpanded) {
- // close to open
- data.node.origin.isLoading = true;
- setTimeout(() => {
- data.node.isExpanded = !data.node.isExpanded;
- data.node.origin.isLoading = false;
- }, 500);
- } else {
- data.node.isExpanded = !data.node.isExpanded;
- }
- }
- }
-
- // 选中节点
- activeNode(data: NzFormatEmitEvent): void {
- if (this.activedNode) {
- this.activedNode = null;
- }
- data.node.isSelected = true;
- this.activedNode = data.node;
- }
-
- dragStart(event: NzFormatEmitEvent): void {
- // disallow drag if root or search
- this.activedNode = null;
- this.dragNodeElement = event.event.srcElement;
- if (this.dragNodeElement.className.indexOf('is-dragging') === -1) {
- this.dragNodeElement.className = event.event.srcElement.className + ' is-dragging';
- }
- }
-
- contextMenu($event: MouseEvent, template: TemplateRef, node: NzTreeNode): void {
- this.dropdown = this.nzDropdownService.create($event, template);
- }
-
- selectDropdown(): void {
- this.dropdown.close();
- // do something
- console.log('dropdown clicked');
- }
-
- constructor(private nzDropdownService: NzDropdownService) {
- }
-
- ngOnInit(): void {
-
- }
-}
diff --git a/components/tree/demo/directory.md b/components/tree/demo/directory.md
new file mode 100644
index 00000000000..c42b600b01d
--- /dev/null
+++ b/components/tree/demo/directory.md
@@ -0,0 +1,14 @@
+---
+order: 8
+title:
+ zh-CN: 目录
+ en-US: directory
+---
+
+## zh-CN
+
+自定义目录树(使用nzTreeTemplate实现,支持右键)。
+
+## en-US
+
+Customize directory tree(with nzTreeTemplate, supported contextmenu).
diff --git a/components/tree/demo/directory.ts b/components/tree/demo/directory.ts
new file mode 100644
index 00000000000..9ac98be6167
--- /dev/null
+++ b/components/tree/demo/directory.ts
@@ -0,0 +1,135 @@
+import { Component, TemplateRef, ViewChild } from '@angular/core';
+import {
+ NzDropdownContextComponent,
+ NzDropdownService,
+ NzFormatEmitEvent,
+ NzTreeComponent,
+ NzTreeNode
+} from 'ng-zorro-antd';
+
+@Component({
+ selector: 'nz-demo-tree-directory',
+ template: `
+
+
+
+
+
+
+
+
+ {{node.title}}
+ created by {{node?.origin?.author | lowercase}}
+
+
+
+ {{node.title}}
+ modified by {{node?.origin?.author | lowercase}}
+
+
+
+ `,
+ styles : [ `
+ :host ::ng-deep .ant-tree {
+ overflow: hidden;
+ margin: 0 -24px;
+ padding: 0 24px;
+ }
+
+ :host ::ng-deep .ant-tree li {
+ padding: 4px 0 0 0;
+ }
+
+ .custom-node {
+ cursor: pointer;
+ line-height: 24px;
+ margin-left: 4px;
+ display: inline-block;
+ margin: 0 -1000px;
+ padding: 0 1000px;
+ }
+
+ .active {
+ background: #1890FF;
+ color: #fff;
+ }
+
+ .file-name, .folder-name {
+ margin-left: 4px;
+ }
+
+ .file-desc, .folder-desc {
+ padding: 0 8px;
+ display: inline-block;
+ background: #87CEFF;
+ color: #FFFFFF;
+ position: relative;
+ left: 12px;
+ }
+ ` ]
+})
+
+export class NzDemoTreeDirectoryComponent {
+ @ViewChild('treeCom') treeCom: NzTreeComponent;
+ dropdown: NzDropdownContextComponent;
+ // actived node
+ activedNode: NzTreeNode;
+ nodes = [ {
+ title : 'parent 0',
+ key : '100',
+ author : 'NG ZORRO',
+ expanded: true,
+ children: [
+ { title: 'leaf 0-0', key: '1000', author: 'NG ZORRO', isLeaf: true },
+ { title: 'leaf 0-1', key: '1001', author: 'NG ZORRO', isLeaf: true }
+ ]
+ }, {
+ title : 'parent 1',
+ key : '101',
+ author : 'NG ZORRO',
+ children: [
+ { title: 'leaf 1-0', key: '1010', author: 'NG ZORRO', isLeaf: true },
+ { title: 'leaf 1-1', key: '1011', author: 'NG ZORRO', isLeaf: true }
+ ]
+ } ];
+
+ openFolder(data: NzTreeNode | NzFormatEmitEvent): void {
+ // do something if u want
+ if (data instanceof NzTreeNode) {
+ data.isExpanded = !data.isExpanded;
+ } else {
+ data.node.isExpanded = !data.node.isExpanded;
+ }
+ }
+
+ activeNode(data: NzFormatEmitEvent): void {
+ if (this.activedNode) {
+ // delete selectedNodeList(u can do anything u want)
+ this.treeCom.nzTreeService.setSelectedNodeList(this.activedNode);
+ }
+ data.node.isSelected = true;
+ this.activedNode = data.node;
+ // add selectedNodeList
+ this.treeCom.nzTreeService.setSelectedNodeList(this.activedNode);
+ }
+
+ contextMenu($event: MouseEvent, template: TemplateRef): void {
+ this.dropdown = this.nzDropdownService.create($event, template);
+ }
+
+ selectDropdown(type: string): void {
+ this.dropdown.close();
+ // do something
+ }
+
+ constructor(private nzDropdownService: NzDropdownService) {
+ }
+}
diff --git a/components/tree/demo/draggable-confirm.md b/components/tree/demo/draggable-confirm.md
index 93898c73c92..b47ab3bd9f0 100644
--- a/components/tree/demo/draggable-confirm.md
+++ b/components/tree/demo/draggable-confirm.md
@@ -7,8 +7,8 @@ title:
## zh-CN
-nzBeforeDrop: 在拖拽放置事件(drop事件)之前做校验, 例如仅允许拖拽到内部(延时一秒)。
+nzBeforeDrop: 在拖拽放置事件(drop事件)之前做校验, 例如仅允许拖拽到内部(延时一秒)、放置前结合modal验证等。
## en-US
-nzBeforeDrop: Validate before drop event, for example only allowed to drag inside(delay 1s).
+nzBeforeDrop: Validate before drop event, for example: only allow to drag inside(delay 1s)、 validate using modal .etc.
\ No newline at end of file
diff --git a/components/tree/demo/draggable-confirm.ts b/components/tree/demo/draggable-confirm.ts
index bff85b99fd1..215ca0d1276 100644
--- a/components/tree/demo/draggable-confirm.ts
+++ b/components/tree/demo/draggable-confirm.ts
@@ -1,100 +1,48 @@
-import { Component } from '@angular/core';
-import { NzFormatBeforeDropEvent, NzFormatEmitEvent, NzModalService, NzTreeNode } from 'ng-zorro-antd';
+import { Component, OnInit } from '@angular/core';
+import { NzFormatBeforeDropEvent, NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
import { of, Observable } from 'rxjs';
import { delay } from 'rxjs/operators';
@Component({
selector: 'nz-demo-tree-draggable-confirm',
template: `
-
+ (nzOnDragStart)="nzAction($event)"
+ (nzOnDragEnter)="nzAction($event)"
+ (nzOnDragLeave)="nzAction($event)"
+ (nzOnDrop)="nzAction($event)"
+ (nzOnDragEnd)="nzAction($event)">
- `,
- styles : [
- `
- :host ::ng-deep .ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected {
- width: calc(100% - 8px);
- }
-
- :host ::ng-deep .ant-tree li span[draggable], :host ::ng-deep .ant-tree li span[draggable="true"] {
- width: calc(100% - 8px);
- }
- `
- ]
+ `
})
-export class NzDemoTreeDraggableConfirmComponent {
- nodes = [
- new NzTreeNode({
- title : 'root1',
+export class NzDemoTreeDraggableConfirmComponent implements OnInit {
+ nodes = [ {
+ title : '0-0',
+ key : '100',
+ expanded: true,
+ children: [ {
+ title : '0-0-0',
key : '1001',
children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- isLeaf: true
- },
- {
- title : 'child1.2',
- key : '100012',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf : true,
- checked : true,
- disabled: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- }
+ { title: '0-0-0-0', key: '10010', isLeaf: true },
+ { title: '0-0-0-1', key: '10011', isLeaf: true }
]
- }),
- new NzTreeNode({
- title : 'root2',
+ }, {
+ title : '0-0-1',
key : '1002',
children: [
- {
- title : 'child2.1',
- key : '10021',
- isLeaf: true
- },
- {
- title : 'child2.2',
- key : '10022',
- children: [
- {
- title : 'grandchild2.2.1',
- key : '100221',
- isLeaf: true
- }
- ]
- }
+ { title: '0-0-1-0', key: '10020', isLeaf: true }
]
- })
- ];
+ } ]
+ } ];
- mouseAction(name: string, e: NzFormatEmitEvent): void {
- if (name !== 'over') {
- console.log(name, e);
- }
+ nzAction(event: NzFormatEmitEvent): void {
+ console.log(event);
}
beforeDrop(arg: NzFormatBeforeDropEvent): Observable {
@@ -105,4 +53,7 @@ export class NzDemoTreeDraggableConfirmComponent {
return of(false);
}
}
+
+ ngOnInit(): void {
+ }
}
diff --git a/components/tree/demo/draggable.ts b/components/tree/demo/draggable.ts
index 8b636dd33d8..f368066f79a 100644
--- a/components/tree/demo/draggable.ts
+++ b/components/tree/demo/draggable.ts
@@ -4,93 +4,77 @@ import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
@Component({
selector: 'nz-demo-tree-draggable',
template: `
-
- `,
+
+
+ `,
styles : [ `
- :host ::ng-deep .ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected {
- width: calc(100% - 8px);
- }
-
- :host ::ng-deep .ant-tree li span[draggable], :host ::ng-deep .ant-tree li span[draggable="true"] {
- width: calc(100% - 8px);
+ :host ::ng-deep .draggable-tree .ant-tree-node-content-wrapper {
+ width: calc(100% - 42px);
}
` ]
})
+
export class NzDemoTreeDraggableComponent implements OnInit {
- nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
+ nodes = [ {
+ title : '0-0',
+ key : '00',
+ expanded: true,
+ children: [ {
+ title : '0-0-0',
+ key : '000',
+ expanded: true,
children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- isLeaf: true
- },
- {
- title : 'child1.2',
- key : '100012',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf : true,
- checked : true,
- disabled: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- }
+ { title: '0-0-0-0', key: '0000', isLeaf: true },
+ { title: '0-0-0-1', key: '0001', isLeaf: true },
+ { title: '0-0-0-2', key: '0002', isLeaf: true }
]
- }),
- new NzTreeNode({
- title : 'root2',
- key : '1002',
+ }, {
+ title : '0-0-1',
+ key : '001',
children: [
- {
- title : 'child2.1',
- key : '10021',
- isLeaf: true
- },
- {
- title : 'child2.2',
- key : '10022',
- children: [
- {
- title : 'grandchild2.2.1',
- key : '100221',
- isLeaf: true
- }
- ]
- }
+ { title: '0-0-1-0', key: '0010', isLeaf: true },
+ { title: '0-0-1-1', key: '0011', isLeaf: true },
+ { title: '0-0-1-2', key: '0012', isLeaf: true }
]
- })
- ];
-
- mouseAction(name: string, e: NzFormatEmitEvent): void {
- if (name !== 'over') {
- console.log(name, e);
- }
- }
+ }, {
+ title: '0-0-2',
+ key : '002'
+ } ]
+ }, {
+ title : '0-1',
+ key : '01',
+ children: [ {
+ title : '0-1-0',
+ key : '010',
+ children: [
+ { title: '0-1-0-0', key: '0100', isLeaf: true },
+ { title: '0-1-0-1', key: '0101', isLeaf: true },
+ { title: '0-1-0-2', key: '0102', isLeaf: true }
+ ]
+ }, {
+ title : '0-1-1',
+ key : '011',
+ children: [
+ { title: '0-1-1-0', key: '0110', isLeaf: true },
+ { title: '0-1-1-1', key: '0111', isLeaf: true },
+ { title: '0-1-1-2', key: '0112', isLeaf: true }
+ ]
+ } ]
+ }, {
+ title : '0-2',
+ key : '02',
+ isLeaf: true
+ } ];
- constructor() {
+ nzEvent(event: NzFormatEmitEvent): void {
+ console.log(event);
}
ngOnInit(): void {
diff --git a/components/tree/demo/dynamic.md b/components/tree/demo/dynamic.md
index f8b7984cb65..c68eb33697c 100644
--- a/components/tree/demo/dynamic.md
+++ b/components/tree/demo/dynamic.md
@@ -1,5 +1,5 @@
---
-order: 7
+order: 4
title:
zh-CN: 异步数据加载
en-US: load data asynchronously
@@ -7,8 +7,8 @@ title:
## zh-CN
-点击展开节点,动态加载数据,直到执行 addChildren() 方法取消加载状态。
+点击展开节点,动态加载数据。
## en-US
-To load data asynchronously when click to expand a treeNode, loading state keeps until excute addChildren().
+To load data asynchronously when click to expand a treeNode.
diff --git a/components/tree/demo/dynamic.ts b/components/tree/demo/dynamic.ts
index afa58b3c6d1..e9bf67263e6 100644
--- a/components/tree/demo/dynamic.ts
+++ b/components/tree/demo/dynamic.ts
@@ -1,48 +1,39 @@
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
@Component({
selector: 'nz-demo-tree-dynamic',
template: `
-
- `
+
+
+ `
})
-export class NzDemoTreeDynamicComponent {
+
+export class NzDemoTreeDynamicComponent implements OnInit {
nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
- children: []
- }),
- new NzTreeNode({
- title : 'root2',
- key : '1002',
- children: []
- }),
- new NzTreeNode({
- title: 'root3',
- key : '1003'
- })
+ { title: 'Expand to load', key: '0' },
+ { title: 'Expand to load', key: '1' },
+ { title: 'Tree Node', key: '2', isLeaf: true }
];
- mouseAction(name: string, e: NzFormatEmitEvent): void {
- if (name === 'expand') {
+ nzEvent(event: NzFormatEmitEvent): void {
+ console.log(event);
+ // load child async
+ if (event.eventName === 'expand') {
setTimeout(_ => {
- if (e.node.getChildren().length === 0 && e.node.isExpanded) {
- e.node.addChildren([
- {
- title: 'childAdd-1',
- key : '10031-' + (new Date()).getTime()
- },
- {
- title : 'childAdd-2',
- key : '10032-' + (new Date()).getTime(),
- isLeaf: true
- } ]);
+ if (event.node.getChildren().length === 0 && event.node.isExpanded) {
+ event.node.addChildren([
+ { title: 'Child Node', key: `${event.node.key}-0` },
+ { title: 'Child Node', key: `${event.node.key}-1` } ]);
}
}, 1000);
}
}
+
+ ngOnInit(): void {
+ }
}
diff --git a/components/tree/demo/line.md b/components/tree/demo/line.md
index b777e858f15..33f6dde4d02 100644
--- a/components/tree/demo/line.md
+++ b/components/tree/demo/line.md
@@ -1,8 +1,8 @@
---
-order: 1
+order: 6
title:
zh-CN: 连接线
- en-US: tree with line
+ en-US: Tree With Line
---
## zh-CN
@@ -11,4 +11,4 @@ title:
## en-US
-Tree With Line
+Tree With Line.
diff --git a/components/tree/demo/line.ts b/components/tree/demo/line.ts
index 26a9a1b199e..cbe34b7a74e 100644
--- a/components/tree/demo/line.ts
+++ b/components/tree/demo/line.ts
@@ -1,92 +1,51 @@
-import { Component } from '@angular/core';
-import { NzTreeNode } from 'ng-zorro-antd';
+import { Component, OnInit } from '@angular/core';
+import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
@Component({
selector: 'nz-demo-tree-line',
template: `
-
- `
+
+
+ `
})
-export class NzDemoTreeLineComponent {
- expandKeys = [ '1001', '10001' ];
- nodes = [
- new NzTreeNode({
- title : 'root1',
+
+export class NzDemoTreeLineComponent implements OnInit {
+ nodes = [ {
+ title : 'parent 1',
+ key : '100',
+ expanded: true,
+ children: [ {
+ title : 'parent 1-0',
key : '1001',
+ expanded: true,
children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.2',
- key : '100012',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf : true,
- disabled: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- },
- {
- title : 'child2',
- key : '10002',
- children: [
- {
- title : 'grandchild2.1',
- key : '1000122',
- isLeaf: true
- },
- {
- title : 'grandchild2.2',
- key : '1000123',
- isLeaf: true
- }
- ]
- }
+ { title: 'leaf', key: '10010', isLeaf: true },
+ { title: 'leaf', key: '10011', isLeaf: true },
+ { title: 'leaf', key: '10012', isLeaf: true }
]
- }),
- new NzTreeNode({
- title : 'root2',
+ }, {
+ title : 'parent 1-1',
key : '1002',
children: [
- {
- title : 'child2.1',
- key : '10021',
- children : [],
- disableCheckbox: true
- },
- {
- title : 'child2.2',
- key : '10022',
- children: [
- {
- title : 'grandchild2.2.1',
- key : '100221',
- isLeaf: true
- }
- ]
- }
+ { title: 'leaf', key: '10020', isLeaf: true }
+ ]
+ }, {
+ title : 'parent 1-2',
+ key : '1003',
+ children: [
+ { title: 'leaf', key: '10030', isLeaf: true },
+ { title: 'leaf', key: '10031', isLeaf: true }
]
- })
- ];
+ } ]
+ } ];
+
+ nzEvent(event: NzFormatEmitEvent): void {
+ console.log(event);
+ }
- mouseAction(name: string, e: any): void {
- console.log(name, e);
+ ngOnInit(): void {
}
}
diff --git a/components/tree/demo/method.md b/components/tree/demo/method.md
deleted file mode 100644
index 8a0a6bcebb0..00000000000
--- a/components/tree/demo/method.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-order: 8
-title:
- zh-CN: 常用方法
- en-US: common methods
----
-
-## zh-CN
-
-Tree组件通过几种常用方法供用户快速获取数据。
-
-## en-US
-
-Tree components provide quick access to data through several common methods.
\ No newline at end of file
diff --git a/components/tree/demo/method.ts b/components/tree/demo/method.ts
deleted file mode 100644
index 27239522da3..00000000000
--- a/components/tree/demo/method.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-import { Component, OnInit, ViewChild } from '@angular/core';
-import { NzFormatEmitEvent, NzTreeComponent, NzTreeNode } from 'ng-zorro-antd';
-
-@Component({
- selector: 'nz-demo-tree-method',
- template: `
-
- `
-})
-
-export class NzDemoTreeMethodComponent implements OnInit {
- @ViewChild('nzTree') nzTree: NzTreeComponent;
- expandKeys = [ '1001', '10001' ];
- checkedKeys = [ '10001' ];
- selectedKeys = [ '10001', '100011' ];
- expandDefault = false;
- nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
- children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- children: []
- },
- {
- title : 'child1.2',
- key : '100012',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf : true,
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- }
- ]
- })
- ];
-
- mouseAction(name: string, event: NzFormatEmitEvent): void {
- console.log(name, event);
- // just for demo, should get in ngAfterViewInit
- console.log('checkedNodes: %o', this.nzTree.getCheckedNodeList());
- console.log('selectedNodes: %o', this.nzTree.getSelectedNodeList());
- console.log('halfCheckedNodes: %o', this.nzTree.getHalfCheckedNodeList());
- console.log(this.nzTree.nzTreeService.getCheckedNodeList());
- }
-
- ngOnInit(): void {
- }
-}
diff --git a/components/tree/demo/search.md b/components/tree/demo/search.md
index 6109df1583d..9a7ccd592c0 100644
--- a/components/tree/demo/search.md
+++ b/components/tree/demo/search.md
@@ -1,8 +1,8 @@
---
-order: 6
+order: 5
title:
zh-CN: 可搜索
- en-US: searchable
+ en-US: Searchable
---
## zh-CN
@@ -11,4 +11,4 @@ title:
## en-US
-Searchable Tree.
+Searchable Tree.
\ No newline at end of file
diff --git a/components/tree/demo/search.ts b/components/tree/demo/search.ts
index a2471204994..c1ff2ff0ba9 100644
--- a/components/tree/demo/search.ts
+++ b/components/tree/demo/search.ts
@@ -1,88 +1,77 @@
-import { Component } from '@angular/core';
-import { NzTreeNode } from 'ng-zorro-antd';
+import { Component, OnInit, ViewChild } from '@angular/core';
+import { NzFormatEmitEvent, NzTreeNode } from 'ng-zorro-antd';
@Component({
selector: 'nz-demo-tree-search',
template: `
-
+
-
- `
+
+
+ `,
+ styles : [ `
+ nz-input-group {
+ padding: 10px 0;
+ }
+ ` ]
})
-export class NzDemoTreeSearchComponent {
+
+export class NzDemoTreeSearchComponent implements OnInit {
+ @ViewChild('treeCom') treeCom;
searchValue;
- nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
+
+ nodes = [ {
+ title : '0-0',
+ key : '0-0',
+ children: [ {
+ title : '0-0-0',
+ key : '0-0-0',
children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- children: []
- },
- {
- title : 'child1.2',
- key : '100012',
- checked : true,
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf: true
- }
- ]
- }
- ]
- },
- {
- title : 'child2',
- key : '10002',
- isLeaf: true
- }
+ { title: '0-0-0-0', key: '0-0-0-0', isLeaf: true },
+ { title: '0-0-0-1', key: '0-0-0-1', isLeaf: true },
+ { title: '0-0-0-2', key: '0-0-0-2', isLeaf: true }
]
- }),
- new NzTreeNode({
- title : 'root2',
- key : '1002',
+ }, {
+ title : '0-0-1',
+ key : '0-0-1',
children: [
- {
- title : 'child2.1',
- key : '10021',
- children: []
- },
- {
- title : 'child1.2',
- key : '10022',
- selectable: false,
- children : [
- {
- title : 'grandchild2.2.1',
- key : '100221',
- isLeaf: true
- }
- ]
- }
+ { title: '0-0-1-0', key: '0-0-1-0', isLeaf: true },
+ { title: '0-0-1-1', key: '0-0-1-1', isLeaf: true },
+ { title: '0-0-1-2', key: '0-0-1-2', isLeaf: true }
]
- })
- ];
+ }, {
+ title : '0-0-2',
+ key : '0-0-2',
+ isLeaf: true
+ } ]
+ }, {
+ title : '0-1',
+ key : '0-1',
+ children: [
+ { title: '0-1-0-0', key: '0-1-0-0', isLeaf: true },
+ { title: '0-1-0-1', key: '0-1-0-1', isLeaf: true },
+ { title: '0-1-0-2', key: '0-1-0-2', isLeaf: true }
+ ]
+ }, {
+ title : '0-2',
+ key : '0-2',
+ isLeaf: true
+ } ];
+
+ nzEvent(event: NzFormatEmitEvent): void {
+ console.log(event, this.treeCom.getMatchedNodeList().map(v => v.title));
+ }
- mouseAction(name: string, e: any): void {
- console.log(name, e);
+ ngOnInit(): void {
}
}
diff --git a/components/tree/doc/index.en-US.md b/components/tree/doc/index.en-US.md
index 710a948e741..95bf33eeca2 100644
--- a/components/tree/doc/index.en-US.md
+++ b/components/tree/doc/index.en-US.md
@@ -14,7 +14,12 @@ Almost anything can be represented in a tree structure. Examples include directo
| Property | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
-| `[ngModel]` | Tree data (Reference NzTreeNode) | NzTreeNode\[] | \[] |
+| `[ngModel]` | Tree data `Deprecated` | NzTreeNode[] | \[] |
+| `[nzDefaultExpandAll]` | Whether to expand all treeNodes `Deprecated` | boolean | false |
+| `[nzDefaultExpandedKeys]` | Specify the keys of the default expanded treeNodes `Deprecated` | string\[] | \[] |
+| `[nzDefaultCheckedKeys]` | Specifies the keys of the default checked treeNodes `Deprecated` | string\[] | \[] |
+| `[nzDefaultSelectedKeys]` | Specifies the keys of the default selected treeNodes `Deprecated` | string\[] | \[] |
+| `[nzData]` | Tree data (Reference NzTreeNode) | NzTreeNode\[] | \[] |
| `[nzCheckable]` | Adds a Checkbox before the treeNodes| boolean | false |
| `[nzShowExpand]` | Show a Expand Icon before the treeNodes | boolean | true |
| `[nzShowLine]` | Shows a connecting line | boolean | false |
@@ -22,10 +27,10 @@ Almost anything can be represented in a tree structure. Examples include directo
| `[nzDraggable]` | Specifies whether this Tree is draggable (IE > 8) | boolean | false |
| `[nzMultiple]` | Allows selecting multiple treeNodes | boolean | false |
| `[nzCheckStrictly]` | Check treeNode precisely; parent treeNode and children treeNodes are not associated | boolean | false |
-| `[nzDefaultExpandAll]` | Whether to expand all treeNodes by default | boolean | false |
-| `[nzDefaultExpandedKeys]` | Specify the keys of the default expanded treeNodes | string\[] | \[] |
-| `[nzDefaultCheckedKeys]` | Specifies the keys of the default checked treeNodes | string\[] | \[] |
-| `[nzDefaultSelectedKeys]` | Specifies the keys of the default selected treeNodes(set nzMultiple to be true) | string\[] | \[] |
+| `[nzExpandAll]` | Whether to expand all treeNodes | boolean | false |
+| `[nzExpandedKeys]` | Specify the keys of the default expanded treeNodes | string\[] | \[] |
+| `[nzCheckedKeys]` | Specifies the keys of the default checked treeNodes | string\[] | \[] |
+| `[nzSelectedKeys]` | Specifies the keys of the default selected treeNodes(set nzMultiple to be true) | string\[] | \[] |
| `[nzSearchValue]` | Filter (highlight) treeNodes (see demo `Searchable`) | string | null |
| `[nzBeforeDrop]` | Drop before the second check, allowing the user to decide whether to allow placement | `(confirm: NzFormatBeforeDropEvent) => Observable` | - |
| `(nzClick)` | Callback function for when the user clicks a treeNode | EventEmitter | - |
@@ -33,7 +38,7 @@ Almost anything can be represented in a tree structure. Examples include directo
| `(nzContextMenu)` | Callback function for when the user right clicks a treeNode | EventEmitter | - |
| `(nzCheckBoxChange)` | Callback function for when user clicks the Checkbox | EventEmitter | - |
| `(nzExpandChange)` | Callback function for when a treeNode is expanded or collapsed |EventEmitter | - |
-| `(nzOnSearchNode)` | Callback function for when filter treeNodes(used with nzSearchValue) | EventEmitter | - |
+| `(nzSearchValueChange)` | Callback function for when filter treeNodes(used with nzSearchValue) | EventEmitter | - |
| `(nzOnDragStart)` | Callback function for when the onDragStart event occurs | EventEmitter | - |
| `(nzOnDragEnter)` | Callback function for when the onDragEnter event occurs | EventEmitter | - |
| `(nzOnDragOver)` | Callback function for when the onDragOver event occurs | EventEmitter | - |
@@ -48,14 +53,16 @@ Almost anything can be represented in a tree structure. Examples include directo
| getCheckedNodeList | get checked nodes(merged) | NzTreeNode[] | [] |
| getSelectedNodeList | get selected nodes | NzTreeNode[] | [] |
| getHalfCheckedNodeList | get half checked nodes | NzTreeNode[] | [] |
+| getExpandedNodeList | get expanded nodes | NzTreeNode[] | [] |
+| getMatchedNodeList | get matched nodes(if nzSearchValue is not null) | NzTreeNode[] | [] |
#### NzTreeNodeOptions props
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| title | Title | string | '---' |
-| key | Used with nzDefaultExpandedKeys / nzDefaultCheckedKeys / nzDefaultSelectedKeys. P.S.: It must be unique in all of treeNodes of the tree!| string | null |
-| children | treeNode's children | array | \[] |
+| key | Must be unique!| string | null |
+| children | TreeNode's children | NzTreeNodeOptions[] | \[] |
| isLeaf | Determines if this is a leaf node(can not be dropped to) | boolean | false |
| checked | Set the treeNode be checked | boolean | false |
| selected | Set the treeNode be selected | boolean | false |
@@ -71,11 +78,12 @@ Almost anything can be represented in a tree structure. Examples include directo
| eventName | Event Name | enum: `click` `dblclick` `contextmenu` `check` `expand` `search` & `dragstart` `dragenter` `dragover` `dragleave` `drop` `dragend` | '' |
| node | The current operation node (such as the target node to drop while dragging) | NzTreeNode | null |
| event | MouseEvent or DragEvent | enum: `MouseEvent` `DragEvent` | null |
-| dragNode? | Current drag node (existing when dragged) | NzTreeNode | null |
-| selectedKeys? | Selected node list (exist when clicked) | array | [] |
-| checkedKeys? | Checked node list (exist when click checkbox) | array | [] |
-| flatCheckedKeys? | Flatten the Checked nodes list (exist when click checkbox) | array | [] |
-| matchededKeys? | matched nodes while searching | array | [] |
+| dragNode? | Current drag node (existing if dragged) | NzTreeNode | null |
+| selectedKeys? | Selected nodes list | NzTreeNode[] | [] |
+| checkedKeys? | Checked nodes list | NzTreeNode[] | [] |
+| matchedKeys? | Matched keys list while searching | NzTreeNode[] | [] |
+| keys? | All nodes's keys list related event(except drag events) | string[] | [] |
+| nodes? | All nodes related event(except drag events) | NzTreeNode[] | [] |
#### NzFormatBeforeDropEvent props
@@ -108,7 +116,9 @@ Almost anything can be represented in a tree structure. Examples include directo
| isMatched | Whether treeNode's title contains nzSearchValue | boolean | `true` / `false` |
| getChildren | Get all children | function | NzTreeNode[] |
| addChildren | Add child nodes, receive NzTreeNode or NzTreeNodeOptions array, the second parameter is the inserted index position | (children: array, index?: number )=>{} | void |
-| clearChildren | clear the treeNode's children | function | void |
+| setChecked | set isChecked & isHalfChecked state,params: checked , halfChecked | (checked: boolean, halfChecked: boolean=false)=>{} | void |
+| setExpanded | set isExpanded state | (value: boolean)=>{} | void |
+| setSelected | set isSelected state | (value: boolean)=>{} | void |
## Note
`NzTreeNodeOptions` accepts your customized properties,use NzTreeNode.origin to get them.
diff --git a/components/tree/doc/index.zh-CN.md b/components/tree/doc/index.zh-CN.md
index b55d21f657a..ee3927c03fc 100644
--- a/components/tree/doc/index.zh-CN.md
+++ b/components/tree/doc/index.zh-CN.md
@@ -15,7 +15,12 @@ subtitle: 树形控件
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
-| `[ngModel]` | 元数据,NzTreeNode数组,单个节点原始结构参考NzTreeNodeOptions | array | \[] |
+| `[ngModel]` | 元数据 `Deprecated` | NzTreeNode[] | \[] |
+| `[nzDefaultExpandAll]` | 默认展开所有节点 `Deprecated` | boolean | false |
+| `[nzDefaultExpandedKeys]` | 展开指定的节点 `Deprecated` | string\[] | \[] |
+| `[nzDefaultCheckedKeys]` | 指定选中复选框的节点 `Deprecated` | string\[] | \[] |
+| `[nzDefaultSelectedKeys]` | 指定选中的节点 `Deprecated` | string\[] | \[] |
+| `[nzData]` | 元数据 | NzTreeNodeOptions[] / NzTreeNode[] | \[] |
| `[nzCheckable]` | 节点前添加 Checkbox 复选框 | boolean | false |
| `[nzShowExpand]` | 节点前添加展开图标 | boolean | true |
| `[nzShowLine]` | 是否展示连接线 | boolean | false |
@@ -23,10 +28,10 @@ subtitle: 树形控件
| `[nzDraggable]` | 设置节点可拖拽(IE>8) | boolean | false |
| `[nzMultiple]` | 支持点选多个节点(节点本身) | boolean | false |
| `[nzCheckStrictly]` | checkable状态下节点选择完全受控(父子节点选中状态不再关联) | boolean | false |
-| `[nzDefaultExpandAll]` | 默认展开所有树节点 | boolean | false |
-| `[nzDefaultExpandedKeys]` | 默认展开指定的树节点 | string\[] | \[] |
-| `[nzDefaultCheckedKeys]` | 默认选中复选框的树节点 | string\[] | \[] |
-| `[nzDefaultSelectedKeys]` | 默认选中的树节点(nzMultiple为true) | string\[] | \[] |
+| `[nzExpandAll]` | 默认展开所有树节点 | boolean | false |
+| `[nzExpandedKeys]` | 展开指定的树节点 | string\[] | \[] |
+| `[nzCheckedKeys]` | 指定选中复选框的树节点 | string\[] | \[] |
+| `[nzSelectedKeys]` | 指定选中的树节点(nzMultiple为true) | string\[] | \[] |
| `[nzSearchValue]` | 按需筛选树高亮节点(结合搜索控件) | string | null |
| `[nzBeforeDrop]` | drop前二次校验,允许用户自行决定是否允许放置 | `(confirm: NzFormatBeforeDropEvent) => Observable` | - |
| `(nzClick)` | 点击树节点触发 | EventEmitter | - |
@@ -34,7 +39,8 @@ subtitle: 树形控件
| `(nzContextMenu)` | 右键树节点触发 | EventEmitter | - |
| `(nzCheckBoxChange)` | 点击树节点 Checkbox 触发 | EventEmitter | - |
| `(nzExpandChange)` | 点击展开树节点图标触发 |EventEmitter | - |
-| `(nzOnSearchNode)` | 搜索节点时调用(与nzSearchValue配合使用) | EventEmitter | - |
+| `(nzSearchValueChange)` | 搜索节点时调用(与nzSearchValue配合使用) | EventEmitter | - |
+| `(nzOnSearchNode)` | 搜索节点时调用(与nzSearchValue配合使用) `Deprecated` | EventEmitter | - |
| `(nzOnDragStart)` | 开始拖拽时调用 | EventEmitter | - |
| `(nzOnDragEnter)` | dragenter 触发时调用 | EventEmitter | - |
| `(nzOnDragOver)` | dragover 触发时调用 | EventEmitter | - |
@@ -50,6 +56,8 @@ subtitle: 树形控件
| getCheckedNodeList | 获取组件 checkBox 被点击选中的节点 | NzTreeNode[] | [] |
| getSelectedNodeList | 获取组件被选中的节点 | NzTreeNode[] | [] |
| getHalfCheckedNodeList | 获取组件半选状态节点 | NzTreeNode[] | [] |
+| getExpandedNodeList | 获取组件展开状态节点 | NzTreeNode[] | [] |
+| getMatchedNodeList | 获取组搜索匹配到的节点 | NzTreeNode[] | [] |
#### NzTreeNodeOptions props
@@ -65,7 +73,7 @@ subtitle: 树形控件
| selectable | 设置节点是否可被选中 | boolean | true |
| disabled | 设置是否禁用节点(不可进行任何操作) | boolean | false |
| disableCheckbox | 设置节点禁用 Checkbox | boolean | false |
-| [key: string] | 自定义数据 | any | - |
+| [key: string] | 自定义数据,可通过 NzTreeNode 的 origin 字段获取 | any | - |
#### NzFormatEmitEvent props
@@ -75,9 +83,12 @@ subtitle: 树形控件
| node | 当前操作节点(拖拽时表示目标节点) | NzTreeNode | null |
| event | 原生事件 | enum: `MouseEvent` `DragEvent` | null |
| dragNode? | 当前拖拽节点(拖拽时存在) | NzTreeNode | null |
-| selectedKeys? | 已选中的节点(单击时存在) | array | [] |
-| checkedKeys? | checkBox 已选中的节点(点击 checkBox 存在) | array | [] |
-| matchededKeys? | 搜索时匹配到的节点 | array | [] |
+| selectedKeys? | 已选中的节点key(单击时存在) | NzTreeNode[] | [] |
+| checkedKeys? | checkBox 已选中的节点key(点击 checkBox 存在) | NzTreeNode[] | [] |
+| matchedKeys? | 搜索时匹配到的节点key | NzTreeNode[] | [] |
+| keys? | 非拖拽事件相关的全部节点的key数组 | string[] | [] |
+| nodes? | 非拖拽事件相关的全部节点 | NzTreeNode[] | [] |
+
#### NzFormatBeforeDropEvent props
@@ -94,7 +105,7 @@ subtitle: 树形控件
| title | 标题 | string | NzTreeNodeOptions.title |
| key | key值 | string | NzTreeNodeOptions.key |
| level | 层级(最顶层为0,子节点逐层加1) | number | number |
-| children | 子节点 | array | array |
+| children | 子节点 | array | NzTreeNode[] |
| origin | 原始节点树结构(用户提供,用于展示额外信息) | NzTreeNodeOptions | - |
| getParentNode | 获取父节点 | function | `NzTreeNode` 或 `null` |
| isLeaf | 是否为叶子节点 | boolean | `true` 或 `false` |
@@ -109,8 +120,11 @@ subtitle: 树形控件
| isLoading | 是否异步加载状态(影响展开图标展示) | boolean | `true` 或 `false` |
| isMatched | title是否包含nzSearchValue(搜索使用) | boolean | `true` 或 `false` |
| getChildren | 获取子节点,返回NzTreeNode数组 | function | NzTreeNode[] |
-| addChildren | 添加子节点,接收NzTreeNode或NzTreeNodeOptions数组,第二个参数为插入的索引位置 | (children: array, index?: number )=>{} | void |
-| clearChildren | 清除子节点 | function | void |
+| addChildren | 添加子节点,接收NzTreeNode或NzTreeNodeOptions数组,第二个参数为插入的索引位置,默认插入末尾 | (children: array, index?: number )=>{} | void |
+| setChecked | 设置checked状态,参数为checked和halfChecked | (checked: boolean, halfChecked: boolean=false)=>{} | void |
+| setExpanded | 设置expanded状态 | (value: boolean)=>{} | void |
+| setSelected | 设置selected状态 | (value: boolean)=>{} | void |
+
## 注意
`NzTreeNodeOptions` 可以接受用户自定义属性,可通过 `NzTreeNode` 的 `origin` 属性取得。
\ No newline at end of file
diff --git a/components/tree/interface.ts b/components/tree/interface.ts
index 15ec82a6e09..b127e73d6c9 100644
--- a/components/tree/interface.ts
+++ b/components/tree/interface.ts
@@ -8,6 +8,8 @@ export interface NzFormatEmitEvent {
selectedKeys?: NzTreeNode[];
checkedKeys?: NzTreeNode[];
matchedKeys?: NzTreeNode[];
+ nodes?: NzTreeNode[];
+ keys?: string[];
}
export interface NzFormatBeforeDropEvent {
diff --git a/components/tree/nz-tree-node.component.html b/components/tree/nz-tree-node.component.html
index 3642f1b8d67..ba9abdb0786 100644
--- a/components/tree/nz-tree-node.component.html
+++ b/components/tree/nz-tree-node.component.html
@@ -1,53 +1,62 @@
-
+
+ [ngClass]="nzNodeSwitcherClass"
+ [class.ant-tree-switcher_open]="isSwitcherOpen"
+ [class.ant-tree-switcher_close]="isSwitcherClose"
+ (click)="_clickExpand($event)">
-
+
-
+ [class.ant-tree-checkbox-disabled]="(nzTreeNode.isDisabled || nzTreeNode.isDisableCheckbox)"
+ (click)="_clickCheckBox($event)">
+
0"
- [class.ant-tree-node-content-wrapper-close]="!nzTreeNode.isExpanded && nzTreeNode.getChildren().length>0"
- [class.ant-tree-node-content-wrapper-normal]="nzTreeNode.getChildren().length>0"
- [attr.draggable]="nzDraggable"
- [attr.aria-grabbed]="nzDraggable">
-
-
-
- {{matchValue[0]}}{{nzSearchValue}}{{matchValue[1]}}
-
-
-
- {{nzTreeNode.title}}
-
+ [class.draggable]="canDraggable">
+
+
+
+
+
+
+
+ {{highlightKeys[0]}}{{nzSearchValue}}{{highlightKeys[1]}}
+
+
+
+ {{nzTreeNode.title}}
+
+
- 0 && nzTreeNode.isExpanded)?'active':'inactive'">
-
+ active', animate('150ms ease-in')),
- transition('active => inactive', animate('150ms ease-out'))
+ transition('inactive => active', animate('100ms ease-in')),
+ transition('active => inactive', animate('100ms ease-out'))
])
]
})
-export class NzTreeNodeComponent implements OnInit, AfterViewInit {
- dragPos = 2;
- prefixCls = 'ant-tree';
- _treeNode;
- _expandAll = false;
- _defaultCheckedKeys = [];
- _defaultExpandedKeys = [];
- _defaultSelectedKeys = [];
- _searchValue = '';
- matchValue = [];
- // 拖动划过状态
- dragPosClass: object = {
- '0' : 'drag-over',
- '1' : 'drag-over-gap-bottom',
- '-1': 'drag-over-gap-top'
- };
-
+export class NzTreeNodeComponent implements OnInit, OnChanges {
@ViewChild('dragElement') dragElement: ElementRef;
- @Input() nzShowLine: boolean;
- @Input() nzShowExpand: boolean;
- @Input() nzDraggable: boolean;
- @Input() nzMultiple: boolean;
- @Input() nzCheckable: boolean;
- @Input() nzAsyncData;
- @Input() nzCheckStrictly: boolean;
+ @Input() @InputBoolean() nzShowLine: boolean;
+ @Input() @InputBoolean() nzShowExpand: boolean;
+ @Input() @InputBoolean() nzDraggable: boolean;
+ @Input() @InputBoolean() nzMultiple: boolean;
+ @Input() @InputBoolean() nzCheckable: boolean;
+ @Input() @InputBoolean() nzAsyncData: boolean;
+ @Input() @InputBoolean() nzCheckStrictly: boolean;
@Input() nzTreeTemplate: TemplateRef;
@Input() nzBeforeDrop: (confirm: NzFormatBeforeDropEvent) => Observable;
@Input()
- set nzTreeNode(node: NzTreeNode) {
- this._treeNode = node;
+ set nzTreeNode(value: NzTreeNode) {
+ // add to checked list & selected list
+ if (value.isChecked) {
+ this.nzTreeService.setCheckedNodeList(value);
+ }
+ // add select list
+ if (value.isSelected) {
+ this.nzTreeService.setSelectedNodeList(value, this.nzMultiple);
+ }
+ if (!value.isLeaf) {
+ this.nzTreeService.setExpandedNodeList(value);
+ }
+ this._nzTreeNode = value;
}
get nzTreeNode(): NzTreeNode {
- return this._treeNode;
+ return this._nzTreeNode;
}
+ // TODO: Deprecated
@Input()
set nzDefaultExpandAll(value: boolean) {
- if (value && this.nzTreeNode) {
- this.nzTreeNode.isExpanded = value;
+ this._nzExpandAll = value;
+ if (value && this.nzTreeNode && !this.nzTreeNode.isLeaf) {
+ this.nzTreeNode.setExpanded(true);
+ this.nzTreeService.setExpandedNodeList(this.nzTreeNode);
}
- this._expandAll = value;
}
get nzDefaultExpandAll(): boolean {
- return this._expandAll;
- }
-
- @Input()
- set nzDefaultCheckedKeys(value: string[]) {
- // should set checked node list
- this._defaultCheckedKeys = value;
- if (value && value.indexOf(this.nzTreeNode.key) > -1) {
- if (this.nzCheckStrictly) {
- this.nzTreeService.setCheckedNodeListStrict(this.nzTreeNode);
- } else {
- this.nzTreeService.setCheckedNodeList(this.nzTreeNode);
- }
- }
- }
-
- get nzDefaultCheckedKeys(): string[] {
- return this._defaultCheckedKeys;
- }
-
- @Input()
- set nzDefaultExpandedKeys(value: string[]) {
- this._defaultExpandedKeys = value;
- if (value && value.indexOf(this.nzTreeNode.key) > -1) {
- this.nzTreeNode.isExpanded = true;
- }
- }
-
- get nzDefaultExpandedKeys(): string[] {
- return this._defaultExpandedKeys;
+ return this._nzExpandAll;
}
+ // default set
@Input()
- set nzDefaultSelectedKeys(value: string[]) {
- this._defaultSelectedKeys = value;
- if (value && !this.nzTreeNode.isDisabled && value.indexOf(this.nzTreeNode.key) > -1) {
- this.nzTreeNode.isSelected = true;
- this.nzTreeService.setSelectedNodeList(this.nzTreeNode, this.nzMultiple);
+ set nzExpandAll(value: boolean) {
+ this._nzExpandAll = value;
+ if (value && this.nzTreeNode && !this.nzTreeNode.isLeaf) {
+ this.nzTreeNode.setExpanded(true);
+ this.nzTreeService.setExpandedNodeList(this.nzTreeNode);
}
}
- get nzDefaultSelectedKeys(): string[] {
- return this._defaultSelectedKeys;
+ get nzExpandAll(): boolean {
+ return this._nzExpandAll;
}
@Input()
set nzSearchValue(value: string) {
+ this.highlightKeys = [];
if (value && this.nzTreeNode.title.includes(value)) {
this.nzTreeNode.isMatched = true;
- this.matchValue = [];
// match the search value
const index = this.nzTreeNode.title.indexOf(value);
- this.matchValue.push(this.nzTreeNode.title.slice(0, index));
- this.matchValue.push(this.nzTreeNode.title.slice(index + value.length, this.nzTreeNode.title.length));
+ this.highlightKeys.push(this.nzTreeNode.title.slice(0, index));
+ this.highlightKeys.push(this.nzTreeNode.title.slice(index + value.length, this.nzTreeNode.title.length));
} else {
// close the node if title does't contain search value
this.nzTreeNode.isMatched = false;
- this.matchValue = [];
}
this._searchValue = value;
}
@@ -151,14 +116,7 @@ export class NzTreeNodeComponent implements OnInit, AfterViewInit {
return this._searchValue;
}
- get loadingStyle(): { [ key: string ]: string } {
- const isLoading = this.nzTreeNode.isLoading && !this.nzTreeNode.isLeaf;
- return {
- position : isLoading ? 'relative' : '',
- transform: isLoading ? 'translateX(0%)' : ''
- };
- }
-
+ // Output
@Output() clickNode: EventEmitter = new EventEmitter();
@Output() dblClick: EventEmitter = new EventEmitter();
@Output() contextMenu: EventEmitter = new EventEmitter();
@@ -171,38 +129,172 @@ export class NzTreeNodeComponent implements OnInit, AfterViewInit {
@Output() nzDrop: EventEmitter = new EventEmitter();
@Output() nzDragEnd: EventEmitter = new EventEmitter();
- constructor(private nzTreeService: NzTreeService, private ngZone: NgZone, private renderer: Renderer2) {
+ // default var
+ prefixCls = 'ant-tree';
+ highlightKeys = [];
+ nzNodeClass = {};
+ nzNodeSwitcherClass = {};
+ nzNodeContentClass = {};
+ nzNodeContentIconClass = {};
+ nzNodeContentLoadingClass = {};
+ nzNodeChildrenClass = {};
+
+ /**
+ * drag var
+ */
+ dragPos = 2;
+ dragPosClass: object = {
+ '0' : 'drag-over',
+ '1' : 'drag-over-gap-bottom',
+ '-1': 'drag-over-gap-top'
+ };
+
+ /**
+ * default set
+ */
+ _nzTreeNode: NzTreeNode;
+ _searchValue = '';
+ _nzExpandAll = false;
+
+ get canDraggable(): boolean | null {
+ return (this.nzDraggable && this.nzTreeNode && !this.nzTreeNode.isDisabled) ? true : null;
}
- ngOnInit(): void {
- if (this.nzTreeNode.isChecked) {
- // associate nodes
- if (this.nzCheckStrictly) {
- this.nzTreeService.setCheckedNodeListStrict(this.nzTreeNode);
- } else {
- this.nzTreeService.setCheckedNodeList(this.nzTreeNode);
+ get isSwitcherOpen(): boolean {
+ return (this.nzTreeNode.isExpanded && !this.nzTreeNode.isLeaf);
+ }
+
+ get isSwitcherClose(): boolean {
+ return (!this.nzTreeNode.isExpanded && !this.nzTreeNode.isLeaf);
+ }
+
+ /**
+ * reset node class
+ */
+ setClassMap(): void {
+ this.nzNodeClass = {
+ [ `${this.prefixCls}-treenode-disabled` ]: this.nzTreeNode.isDisabled
+ };
+ this.nzNodeSwitcherClass = {
+ [ `${this.prefixCls}-switcher` ] : true,
+ [ `${this.prefixCls}-switcher-noop` ]: this.nzTreeNode.isLeaf
+ };
+ this.nzNodeContentClass = {
+ [ `${this.prefixCls}-node-content-wrapper` ]: true
+ };
+ this.nzNodeContentIconClass = {
+ [ `${this.prefixCls}-iconEle` ] : true,
+ [ `${this.prefixCls}-icon__customize` ]: true
+ };
+ this.nzNodeContentLoadingClass = {
+ [ `${this.prefixCls}-iconEle` ]: true
+ };
+ this.nzNodeChildrenClass = {
+ [ `${this.prefixCls}-child-tree` ] : true,
+ [ `${this.prefixCls}-child-tree-open` ]: true
+ };
+ }
+
+ /**
+ * click node to select, 200ms to dbl click
+ */
+ @HostListener('click', [ '$event' ])
+ nzClick(event: MouseEvent): void {
+ event.preventDefault();
+ event.stopPropagation();
+ if (this.nzTreeNode.isSelectable) {
+ this.nzTreeService.setNodeActive(this.nzTreeNode, this.nzMultiple);
+ }
+ this.clickNode.emit(this.nzTreeService.formatEvent('click', this.nzTreeNode, event));
+ }
+
+ @HostListener('dblclick', [ '$event' ])
+ nzDblClick(event: MouseEvent): void {
+ event.preventDefault();
+ event.stopPropagation();
+ this.dblClick.emit(this.nzTreeService.formatEvent('dblclick', this.nzTreeNode, event));
+ }
+
+ /**
+ * @param event
+ */
+ @HostListener('contextmenu', [ '$event' ])
+ nzContextMenu(event: MouseEvent): void {
+ event.preventDefault();
+ event.stopPropagation();
+ this.contextMenu.emit(this.nzTreeService.formatEvent('contextmenu', this.nzTreeNode, event));
+ }
+
+ /**
+ * collapse node
+ * @param event
+ */
+ _clickExpand(event: MouseEvent): void {
+ event.preventDefault();
+ event.stopPropagation();
+ if (!this.nzTreeNode.isLoading && !this.nzTreeNode.isLeaf) {
+ // set async state
+ if (this.nzAsyncData && this.nzTreeNode.getChildren().length === 0 && !this.nzTreeNode.isExpanded) {
+ this.nzTreeNode.isLoading = true;
}
+ this.nzTreeNode.setExpanded(!this.nzTreeNode.isExpanded);
+ this.nzTreeService.setExpandedNodeList(this.nzTreeNode);
+ this.clickExpand.emit(this.nzTreeService.formatEvent('expand', this.nzTreeNode, event));
}
- // add select list
- if (this.nzTreeNode.isSelected) {
- this.nzTreeService.setSelectedNodeList(this.nzTreeNode, this.nzMultiple);
+ }
+
+ /**
+ * check node
+ * @param event
+ */
+ _clickCheckBox(event: MouseEvent): void {
+ event.preventDefault();
+ event.stopPropagation();
+ // return if node is disabled
+ if (isCheckDisabled(this.nzTreeNode)) {
+ return;
+ }
+ this.nzTreeNode.setChecked(!this.nzTreeNode.isChecked);
+ this.nzTreeService.setCheckedNodeList(this.nzTreeNode);
+ if (!this.nzCheckStrictly) {
+ this.nzTreeService.conduct(this.nzTreeNode);
}
+ this.clickCheckBox.emit(this.nzTreeService.formatEvent('check', this.nzTreeNode, event));
+ }
+
+ /**
+ * drag event
+ * @param e
+ */
+ clearDragClass(): void {
+ const dragClass = [ 'drag-over-gap-top', 'drag-over-gap-bottom', 'drag-over' ];
+ dragClass.forEach(e => {
+ this.renderer.removeClass(this.dragElement.nativeElement, e);
+ });
}
handleDragStart(e: DragEvent): void {
e.stopPropagation();
+ try {
+ // ie throw error
+ // firefox-need-it
+ e.dataTransfer.setData('text/plain', '');
+ } catch (error) {
+ // empty
+ }
this.nzTreeService.setSelectedNode(this.nzTreeNode);
- this.nzTreeNode.isExpanded = false;
+ this.nzTreeNode.setExpanded(false);
this.nzDragStart.emit(this.nzTreeService.formatEvent('dragstart', null, e));
}
handleDragEnter(e: DragEvent): void {
e.preventDefault();
e.stopPropagation();
+ // reset position
+ this.dragPos = 2;
this.ngZone.run(() => {
- this.nzTreeService.targetNode = this.nzTreeNode;
if ((this.nzTreeNode !== this.nzTreeService.getSelectedNode()) && !this.nzTreeNode.isLeaf) {
- this.nzTreeNode.isExpanded = true;
+ this.nzTreeNode.setExpanded(true);
}
});
this.nzDragEnter.emit(this.nzTreeService.formatEvent('dragenter', this.nzTreeNode, e));
@@ -211,11 +303,12 @@ export class NzTreeNodeComponent implements OnInit, AfterViewInit {
handleDragOver(e: DragEvent): void {
e.preventDefault();
e.stopPropagation();
- if (this.dragPos !== this.nzTreeService.calcDropPosition(e)) {
- this._clearDragClass();
- this.dragPos = this.nzTreeService.calcDropPosition(e);
+ const dropPosition = this.nzTreeService.calcDropPosition(e);
+ if (this.dragPos !== dropPosition) {
+ this.clearDragClass();
+ this.dragPos = dropPosition;
+ // leaf node will pass
if (!(this.dragPos === 0 && this.nzTreeNode.isLeaf)) {
- // leaf node can not be inserted
this.renderer.addClass(this.dragElement.nativeElement, this.dragPosClass[ this.dragPos ]);
}
}
@@ -225,7 +318,7 @@ export class NzTreeNodeComponent implements OnInit, AfterViewInit {
handleDragLeave(e: DragEvent): void {
e.stopPropagation();
this.ngZone.run(() => {
- this._clearDragClass();
+ this.clearDragClass();
});
this.nzDragLeave.emit(this.nzTreeService.formatEvent('dragleave', this.nzTreeNode, e));
}
@@ -233,28 +326,32 @@ export class NzTreeNodeComponent implements OnInit, AfterViewInit {
handleDragDrop(e: DragEvent): void {
e.preventDefault();
e.stopPropagation();
- this.dragPos = this.nzTreeService.calcDropPosition(e);
this.ngZone.run(() => {
+ this.clearDragClass();
+ if (this.nzTreeService.getSelectedNode() === this.nzTreeNode) {
+ console.log('Can not be dropped to self node(include dragNode\'s children node)');
+ return;
+ } else if (this.dragPos === 0 && this.nzTreeNode.isLeaf) {
+ console.log('Can not drop to leaf node');
+ return;
+ }
// pass if node is leafNo
- if (this.nzTreeNode !== this.nzTreeService.getSelectedNode() && !(this.dragPos === 0 && this.nzTreeNode.isLeaf)) {
- if (this.nzBeforeDrop) {
- this.nzBeforeDrop({
- dragNode: this.nzTreeService.getSelectedNode(),
- node : this.nzTreeNode,
- pos : this.dragPos
- }).subscribe((canDrop: boolean) => {
- if (canDrop) {
- this.nzTreeService.dropAndApply(this.nzTreeNode, this.dragPos);
- }
- this.nzDrop.emit(this.nzTreeService.formatEvent('drop', this.nzTreeNode, e));
- this.nzDragEnd.emit(this.nzTreeService.formatEvent('dragend', this.nzTreeNode, e));
- });
- } else {
- this.nzTreeService.dropAndApply(this.nzTreeNode, this.dragPos);
+ if (this.nzBeforeDrop) {
+ this.nzBeforeDrop({
+ dragNode: this.nzTreeService.getSelectedNode(),
+ node : this.nzTreeNode,
+ pos : this.dragPos
+ }).subscribe((canDrop: boolean) => {
+ if (canDrop) {
+ this.nzTreeService.dropAndApply(this.nzTreeNode, this.dragPos);
+ }
this.nzDrop.emit(this.nzTreeService.formatEvent('drop', this.nzTreeNode, e));
- }
+ this.nzDragEnd.emit(this.nzTreeService.formatEvent('dragend', this.nzTreeNode, e));
+ });
+ } else if (this.nzTreeNode) {
+ this.nzTreeService.dropAndApply(this.nzTreeNode, this.dragPos);
+ this.nzDrop.emit(this.nzTreeService.formatEvent('drop', this.nzTreeNode, e));
}
- this._clearDragClass();
});
}
@@ -269,80 +366,22 @@ export class NzTreeNodeComponent implements OnInit, AfterViewInit {
});
}
- ngAfterViewInit(): void {
- if (this.nzDraggable) {
- this.ngZone.runOutsideAngular(() => {
- fromEvent(this.dragElement.nativeElement, 'dragstart').subscribe((e: DragEvent) => this.handleDragStart(e));
- fromEvent(this.dragElement.nativeElement, 'dragenter').subscribe((e: DragEvent) => this.handleDragEnter(e));
- fromEvent(this.dragElement.nativeElement, 'dragover').subscribe((e: DragEvent) => this.handleDragOver(e));
- fromEvent(this.dragElement.nativeElement, 'dragleave').subscribe((e: DragEvent) => this.handleDragLeave(e));
- fromEvent(this.dragElement.nativeElement, 'drop').subscribe((e: DragEvent) => this.handleDragDrop(e));
- fromEvent(this.dragElement.nativeElement, 'dragend').subscribe((e: DragEvent) => this.handleDragEnd(e));
- });
- }
- }
-
- _clearDragClass(): void {
- const dragClass = [ 'drag-over-gap-top', 'drag-over-gap-bottom', 'drag-over' ];
- dragClass.forEach(e => {
- this.renderer.removeClass(this.dragElement.nativeElement, e);
+ constructor(private nzTreeService: NzTreeService, private ngZone: NgZone, private renderer: Renderer2, private elRef: ElementRef) {
+ ngZone.runOutsideAngular(() => {
+ fromEvent(this.elRef.nativeElement, 'dragstart').subscribe((e: DragEvent) => this.handleDragStart(e));
+ fromEvent(this.elRef.nativeElement, 'dragenter').subscribe((e: DragEvent) => this.handleDragEnter(e));
+ fromEvent(this.elRef.nativeElement, 'dragover').subscribe((e: DragEvent) => this.handleDragOver(e));
+ fromEvent(this.elRef.nativeElement, 'dragleave').subscribe((e: DragEvent) => this.handleDragLeave(e));
+ fromEvent(this.elRef.nativeElement, 'drop').subscribe((e: DragEvent) => this.handleDragDrop(e));
+ fromEvent(this.elRef.nativeElement, 'dragend').subscribe((e: DragEvent) => this.handleDragEnd(e));
});
}
- _clickNode($event: MouseEvent, node: NzTreeNode): void {
- $event.preventDefault();
- $event.stopPropagation();
- if (this.nzTreeNode.isSelectable && !this.nzTreeNode.isDisabled) {
- this.nzTreeService.initNodeActive(this.nzTreeNode, this.nzMultiple);
- }
- this.clickNode.emit(this.nzTreeService.formatEvent('click', node, $event));
- }
-
- _dblClickNode($event: MouseEvent, node: NzTreeNode): void {
- $event.preventDefault();
- $event.stopPropagation();
- this.dblClick.emit(this.nzTreeService.formatEvent('dblclick', node, $event));
- }
-
- _contextMenuNode($event: MouseEvent, node: NzTreeNode): void {
- $event.preventDefault();
- $event.stopPropagation();
- this.contextMenu.emit(this.nzTreeService.formatEvent('contextmenu', node, $event));
- }
-
- _clickCheckBox($event: MouseEvent, node: NzTreeNode): void {
- $event.preventDefault();
- $event.stopPropagation();
- // return if node is disabled
- if (node.isDisableCheckbox || node.isDisabled) {
- return;
- }
- node.isChecked = !node.isChecked;
- if (this.nzCheckStrictly) {
- node.isAllChecked = node.isChecked;
- node.isHalfChecked = false;
- this.nzTreeService.setCheckedNodeListStrict(this.nzTreeNode);
- } else {
- this.nzTreeService.checkTreeNode(node);
- this.nzTreeService.setCheckedNodeList(this.nzTreeNode);
- }
- this.clickCheckBox.emit(this.nzTreeService.formatEvent('check', node, $event));
+ ngOnInit(): void {
+ this.setClassMap();
}
- _clickExpand($event: MouseEvent, node: NzTreeNode): void {
- $event.preventDefault();
- $event.stopPropagation();
- if (!this.nzTreeNode.isLoading) {
- if (!node.isLeaf) {
- // set async state
- if (this.nzAsyncData && this.nzTreeNode.getChildren().length === 0 && !this.nzTreeNode.isExpanded) {
- this.nzTreeNode.isLoading = true;
- }
- node.isExpanded = !this.nzTreeNode.isExpanded;
- }
- if (!this.nzTreeNode.isLeaf) {
- this.clickExpand.emit(this.nzTreeService.formatEvent('expand', node, $event));
- }
- }
+ ngOnChanges(changes: SimpleChanges): void {
+ this.setClassMap();
}
}
diff --git a/components/tree/nz-tree-node.ts b/components/tree/nz-tree-node.ts
index 9b569cc2235..3d3a1633a1d 100644
--- a/components/tree/nz-tree-node.ts
+++ b/components/tree/nz-tree-node.ts
@@ -1,6 +1,7 @@
export interface NzTreeNodeOptions {
title: string;
key: string;
+ icon?: string;
isLeaf?: boolean;
checked?: boolean;
selected?: boolean;
@@ -9,8 +10,9 @@ export interface NzTreeNodeOptions {
disableCheckbox?: boolean;
expanded?: boolean;
children?: NzTreeNodeOptions[];
+
// tslint:disable-next-line:no-any
- [key: string]: any;
+ [ key: string ]: any;
}
export class NzTreeNode {
@@ -35,29 +37,26 @@ export class NzTreeNode {
isMatched: boolean;
constructor(option: NzTreeNodeOptions, parent: NzTreeNode = null) {
- this.title = option.title || '---';
+ this.title = option.title || 'undefined';
this.key = option.key || null;
this.isLeaf = option.isLeaf || false;
this.origin = option;
-
this.children = [];
this.parentNode = parent;
-
// option params
this.isChecked = option.checked || false;
this.isSelectable = option.disabled || (option.selectable === false ? false : true);
this.isDisabled = option.disabled || false;
this.isDisableCheckbox = option.disableCheckbox || false;
- this.isExpanded = option.expanded || false;
-
+ this.isExpanded = option.isLeaf ? false : (option.expanded || false);
this.isAllChecked = option.checked || false;
this.isHalfChecked = false;
- this.isSelected = option.selected || false;
+ this.isSelected = (!option.disabled && option.selected) || false;
this.isLoading = false;
this.isMatched = false;
/**
- * 初始化时父节点checked状态影响全部子节点
+ * parent's checked status will affect children while initializing
*/
if (parent) {
this.level = parent.level + 1;
@@ -76,6 +75,23 @@ export class NzTreeNode {
}
}
+ public setChecked(checked: boolean = false, halfChecked: boolean = false): void {
+ this.origin.checked = checked;
+ this.isChecked = checked;
+ this.isAllChecked = checked;
+ this.isHalfChecked = halfChecked;
+ }
+
+ public setExpanded(value: boolean): void {
+ this.origin.expanded = value;
+ this.isExpanded = value;
+ }
+
+ public setSelected(value: boolean): void {
+ this.origin.selected = value;
+ this.isSelected = value;
+ }
+
public getParentNode(): NzTreeNode {
return this.parentNode;
}
@@ -89,35 +105,30 @@ export class NzTreeNode {
*/
// tslint:disable-next-line:no-any
public addChildren(children: any[], childPos: number = -1): void {
- if (this.isLeaf) {
- // remove loading state
- this.isLoading = false;
- } else {
+ if (!this.isLeaf) {
children.forEach(
(node) => {
- let tNode = node;
- if (tNode instanceof NzTreeNode) {
- tNode = new NzTreeNode({
- checked: !tNode.origin.disabled && !tNode.origin.disableCheckbox && this.isChecked,
- ...(tNode.origin as NzTreeNodeOptions)
- }, this);
+ const refreshLevel = (n: NzTreeNode) => {
+ n.getChildren().forEach(c => {
+ c.level = c.getParentNode().level + 1;
+ refreshLevel(c);
+ });
+ };
+ let child = node;
+ if (child instanceof NzTreeNode) {
+ child.parentNode = this;
} else {
- node.checked = !node.disabled && !node.disableCheckbox && this.isChecked;
- tNode = new NzTreeNode(node, this);
+ child = new NzTreeNode(node, this);
}
- tNode.level = this.level + 1;
+ child.level = this.level + 1;
+ refreshLevel(child);
try {
- childPos === -1 ? this.children.push(tNode) : this.children.splice(childPos, 0, tNode);
+ childPos === -1 ? this.children.push(child) : this.children.splice(childPos, 0, child);
} catch (e) {
-
}
});
// remove loading state
this.isLoading = false;
}
}
-
- public clearChildren(): void {
- this.children = [];
- }
}
diff --git a/components/tree/nz-tree-util.ts b/components/tree/nz-tree-util.ts
new file mode 100644
index 00000000000..07215940f6f
--- /dev/null
+++ b/components/tree/nz-tree-util.ts
@@ -0,0 +1,11 @@
+import { NzTreeNode } from './nz-tree-node';
+
+export function isCheckDisabled(node: NzTreeNode): boolean {
+ const { isDisabled, isDisableCheckbox } = node;
+ return !!(isDisabled || isDisableCheckbox);
+}
+
+// tslint:disable-next-line:no-any
+export function isInArray(needle: any, haystack: any[]): boolean {
+ return (haystack.length > 0 && haystack.indexOf(needle) > -1);
+}
diff --git a/components/tree/nz-tree.component.html b/components/tree/nz-tree.component.html
index 95f2d3a429a..b16cf9e4ac7 100644
--- a/components/tree/nz-tree.component.html
+++ b/components/tree/nz-tree.component.html
@@ -1,32 +1,32 @@
-
+
+ (nzDragEnd)="nzOnDragEnd.emit($event)">
+
\ No newline at end of file
diff --git a/components/tree/nz-tree.component.ts b/components/tree/nz-tree.component.ts
index 26d9d64ceb9..89e98b9d221 100644
--- a/components/tree/nz-tree.component.ts
+++ b/components/tree/nz-tree.component.ts
@@ -1,8 +1,17 @@
-import { forwardRef, Component, ContentChild, EventEmitter, Input, OnInit, Output, TemplateRef } from '@angular/core';
+import {
+ forwardRef,
+ Component,
+ ContentChild,
+ EventEmitter,
+ Input,
+ OnDestroy,
+ OnInit, Output, TemplateRef
+} from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
-import { Observable } from 'rxjs';
-
-import { NzFormatBeforeDropEvent, NzFormatEmitEvent } from './interface';
+import { Observable, Subject, Subscription } from 'rxjs';
+import { isNotNil } from '../core/util/check';
+import { InputBoolean } from '../core/util/convert';
+import { NzFormatBeforeDropEvent, NzFormatEmitEvent } from '../tree/interface';
import { NzTreeNode } from './nz-tree-node';
import { NzTreeService } from './nz-tree.service';
@@ -18,60 +27,112 @@ import { NzTreeService } from './nz-tree.service';
}
]
})
-export class NzTreeComponent implements OnInit {
- _searchValue;
- _showLine = false;
- _prefixCls = 'ant-tree';
- classMap = {
- [ this._prefixCls ] : true,
- [ this._prefixCls + '-show-line' ]: false,
- [ 'draggable-tree' ] : false
- };
- ngModelNodes: NzTreeNode[] = [];
- defaultCheckedKeys: string[] = [];
- @ContentChild('nzTreeTemplate') nzTreeTemplate: TemplateRef<{}>;
-
- @Input() nzCheckStrictly: boolean = false;
- @Input() nzCheckable;
- @Input() nzShowExpand: boolean = true;
- @Input() nzAsyncData: boolean = false;
- @Input() nzDraggable;
- @Input() nzMultiple;
- @Input() nzDefaultExpandAll: boolean = false;
- @Input() nzDefaultExpandedKeys: string[] = [];
- @Input() nzDefaultSelectedKeys: string[] = [];
+
+export class NzTreeComponent implements OnInit, OnDestroy {
+ @Input() @InputBoolean() nzShowIcon = false;
+ @Input() @InputBoolean() nzShowLine = false;
+ @Input() @InputBoolean() nzCheckStrictly = false;
+ @Input() @InputBoolean() nzCheckable = false;
+ @Input() @InputBoolean() nzShowExpand = true;
+ @Input() @InputBoolean() nzAsyncData = false;
+ @Input() @InputBoolean() nzDraggable = false;
+ @Input() @InputBoolean() nzMultiple = false;
+ @Input() @InputBoolean() nzExpandAll: boolean = false;
+ // TODO: Deprecated
+ @Input() @InputBoolean() nzDefaultExpandAll: boolean = false;
@Input() nzBeforeDrop: (confirm: NzFormatBeforeDropEvent) => Observable;
+
+ @Input()
+ // tslint:disable-next-line:no-any
+ set nzData(value: any[]) {
+ if (Array.isArray(value) && value.length > 0) {
+ if (!this.nzTreeService.isArrayOfNzTreeNode(value)) {
+ // has not been new NzTreeNode
+ this.nzNodes = value.map(item => (new NzTreeNode(item)));
+ } else {
+ this.nzNodes = value;
+ }
+ this.nzTreeService.conductOption.isCheckStrictly = this.nzCheckStrictly;
+ this.nzTreeService.initTree(this.nzNodes);
+ } else {
+ if (value !== null) {
+ console.log('nzData only accepts an array and should be not empty');
+ }
+ }
+ }
+
+ /**
+ * TODO: Deprecated
+ */
+ @Input()
+ set nzDefaultExpandedKeys(value: string[]) {
+ setTimeout(() => {
+ this.nzDefaultSubject.next({ type: 'nzExpandedKeys', keys: value });
+ });
+ }
+
+ @Input()
+ set nzDefaultSelectedKeys(value: string[]) {
+ setTimeout(() => {
+ this.nzDefaultSubject.next({ type: 'nzSelectedKeys', keys: value });
+ });
+ }
+
@Input()
set nzDefaultCheckedKeys(value: string[]) {
- this.defaultCheckedKeys = value;
- this.nzTreeService.initTreeNodes(this.ngModelNodes, this.nzDefaultCheckedKeys, this.nzCheckStrictly);
+ setTimeout(() => {
+ this.nzDefaultSubject.next({ type: 'nzCheckedKeys', keys: value });
+ });
}
- get nzDefaultCheckedKeys(): string[] {
- return this.defaultCheckedKeys;
+
+ /**
+ * END Deprecated
+ */
+
+ @Input()
+ set nzExpandedKeys(value: string[]) {
+ setTimeout(() => {
+ this.nzDefaultSubject.next({ type: 'nzExpandedKeys', keys: value });
+ });
}
@Input()
- set nzShowLine(value: boolean) {
- this._showLine = value;
- this.setClassMap();
+ set nzSelectedKeys(value: string[]) {
+ setTimeout(() => {
+ this.nzDefaultSubject.next({ type: 'nzSelectedKeys', keys: value });
+ });
}
- get nzShowLine(): boolean {
- return this._showLine;
+ @Input()
+ set nzCheckedKeys(value: string[]) {
+ setTimeout(() => {
+ this.nzDefaultSubject.next({ type: 'nzCheckedKeys', keys: value });
+ });
}
@Input()
set nzSearchValue(value: string) {
this._searchValue = value;
this.nzTreeService.searchExpand(value);
- this.nzOnSearchNode.emit(this.nzTreeService.formatEvent('search', null, null));
+ if (isNotNil(value)) {
+ this.nzSearchValueChange.emit(this.nzTreeService.formatEvent('search', null, null));
+ this.nzOnSearchNode.emit(this.nzTreeService.formatEvent('search', null, null));
+ }
}
get nzSearchValue(): string {
return this._searchValue;
}
+ // model bind
+ @Output() nzExpandedKeysChange: EventEmitter = new EventEmitter();
+ @Output() nzSelectedKeysChange: EventEmitter = new EventEmitter();
+ @Output() nzCheckedKeysChange: EventEmitter = new EventEmitter();
+
+ @Output() nzSearchValueChange: EventEmitter = new EventEmitter();
+ // TODO: Deprecated
@Output() nzOnSearchNode: EventEmitter = new EventEmitter();
+
@Output() nzClick: EventEmitter = new EventEmitter();
@Output() nzDblClick: EventEmitter = new EventEmitter();
@Output() nzContextMenu: EventEmitter = new EventEmitter();
@@ -85,17 +146,20 @@ export class NzTreeComponent implements OnInit {
@Output() nzOnDrop: EventEmitter = new EventEmitter();
@Output() nzOnDragEnd: EventEmitter = new EventEmitter();
+ // tslint:disable-next-line:no-any
+ @ContentChild('nzTreeTemplate') nzTreeTemplate: TemplateRef;
+ _searchValue = '';
+ // tslint:disable-next-line:no-any
+ nzDefaultSubject = new Subject();
+ nzDefaultSubscription: Subscription;
+ nzNodes: NzTreeNode[] = [];
+ prefixCls = 'ant-tree';
+ nzTreeClass = {};
+
+ // TODO: Deprecated
onChange: (value: NzTreeNode[]) => void = () => null;
onTouched: () => void = () => null;
- setClassMap(): void {
- this.classMap = {
- [ this._prefixCls ] : true,
- [ this._prefixCls + '-show-line' ]: this.nzShowLine,
- [ 'draggable-tree' ] : this.nzDraggable
- };
- }
-
/**
* public function
*/
@@ -111,19 +175,42 @@ export class NzTreeComponent implements OnInit {
return this.nzTreeService.getHalfCheckedNodeList();
}
- // ngModel
+ getExpandedNodeList(): NzTreeNode[] {
+ return this.nzTreeService.getExpandedNodeList();
+ }
+
+ getMatchedNodeList(): NzTreeNode[] {
+ return this.nzTreeService.getMatchedNodeList();
+ }
+
+ setClassMap(): void {
+ this.nzTreeClass = {
+ [ this.prefixCls ] : true,
+ [ this.prefixCls + '-show-line' ]: this.nzShowLine,
+ [ `${this.prefixCls}-icon-hide` ]: !this.nzShowIcon,
+ [ 'draggable-tree' ] : this.nzDraggable
+ };
+ }
+
+ // TODO: Deprecated
writeValue(value: NzTreeNode[]): void {
- if (value) {
- this.ngModelNodes = value;
- this.nzTreeService.initTreeNodes(this.ngModelNodes, this.nzDefaultCheckedKeys, this.nzCheckStrictly);
- this.onChange(value);
+ if (Array.isArray(value) && value.length > 0) {
+ this.nzNodes = value;
+ this.nzTreeService.conductOption.isCheckStrictly = this.nzCheckStrictly;
+ this.nzTreeService.initTree(this.nzNodes);
+ } else {
+ if (value !== null) {
+ console.log('ngModel only accepts an array and should be not empty');
+ }
}
}
+ // TODO: Deprecated
registerOnChange(fn: (_: NzTreeNode[]) => void): void {
this.onChange = fn;
}
+ // TODO: Deprecated
registerOnTouched(fn: () => void): void {
this.onTouched = fn;
}
@@ -132,5 +219,32 @@ export class NzTreeComponent implements OnInit {
}
ngOnInit(): void {
+ this.setClassMap();
+ this.nzDefaultSubscription = this.nzDefaultSubject.subscribe((data: { type: string, keys: string[] }) => {
+ if (data.keys.length === 0) {
+ return;
+ }
+ switch (data.type) {
+ case 'nzExpandedKeys':
+ this.nzTreeService.calcExpandedKeys(data.keys, this.nzNodes);
+ this.nzExpandedKeysChange.emit(data.keys);
+ break;
+ case 'nzSelectedKeys':
+ this.nzTreeService.calcSelectedKeys(data.keys, this.nzNodes, this.nzMultiple);
+ this.nzSelectedKeysChange.emit(data.keys);
+ break;
+ case 'nzCheckedKeys':
+ this.nzTreeService.calcCheckedKeys(data.keys, this.nzNodes, this.nzCheckStrictly);
+ this.nzCheckedKeysChange.emit(data.keys);
+ break;
+ }
+ });
+ }
+
+ ngOnDestroy(): void {
+ if (this.nzDefaultSubscription) {
+ this.nzDefaultSubscription.unsubscribe();
+ this.nzDefaultSubscription = null;
+ }
}
}
diff --git a/components/tree/nz-tree.module.ts b/components/tree/nz-tree.module.ts
index 221c015df91..5578b979b5b 100644
--- a/components/tree/nz-tree.module.ts
+++ b/components/tree/nz-tree.module.ts
@@ -4,9 +4,19 @@ import { NzTreeNodeComponent } from './nz-tree-node.component';
import { NzTreeComponent } from './nz-tree.component';
@NgModule({
- imports : [ CommonModule ],
- declarations: [ NzTreeComponent, NzTreeNodeComponent ],
- exports : [ NzTreeComponent, NzTreeNodeComponent ]
+ imports : [
+ CommonModule
+ ],
+ declarations: [
+ NzTreeComponent,
+ NzTreeNodeComponent
+ ],
+ exports : [
+ NzTreeComponent,
+ NzTreeNodeComponent
+ ]
})
+
export class NzTreeModule {
+
}
diff --git a/components/tree/nz-tree.service.ts b/components/tree/nz-tree.service.ts
index 827f39e1f2e..c806bc4ae77 100644
--- a/components/tree/nz-tree.service.ts
+++ b/components/tree/nz-tree.service.ts
@@ -1,309 +1,412 @@
import { Injectable } from '@angular/core';
-
+import { isNotNil } from '../core/util/check';
import { NzFormatEmitEvent } from './interface';
import { NzTreeNode } from './nz-tree-node';
+import { isCheckDisabled, isInArray } from './nz-tree-util';
@Injectable()
export class NzTreeService {
DRAG_SIDE_RANGE = 0.25;
DRAG_MIN_GAP = 2;
+ conductOption: {
+ isCheckStrictly: boolean
+ } = {
+ isCheckStrictly: false
+ };
selectedNode: NzTreeNode;
targetNode: NzTreeNode;
rootNodes: NzTreeNode[] = [];
selectedNodeList: NzTreeNode[] = [];
+ expandedNodeList: NzTreeNode[] = [];
checkedNodeList: NzTreeNode[] = [];
halfCheckedNodeList: NzTreeNode[] = [];
matchedNodeList: NzTreeNode[] = [];
/**
- * init data to NzTreeNode
+ * reset tree nodes will clear default node list
*/
- initCheckedStatus(childNode: NzTreeNode, defaultCheckedKeys: string[], nzCheckStrictly: boolean): void {
- if (defaultCheckedKeys.indexOf(childNode.key) > -1) {
- childNode.isChecked = true;
- childNode.isAllChecked = true;
- childNode.isHalfChecked = false;
- }
- if (childNode.getChildren()) {
- childNode.getChildren().forEach((child) => {
- // will change child status
- if (!nzCheckStrictly && childNode.isChecked && !child.isDisabled && !child.isDisableCheckbox) {
- child.isChecked = true;
- child.isAllChecked = true;
- child.isHalfChecked = false;
- }
- this.initCheckedStatus(child, defaultCheckedKeys, nzCheckStrictly);
- });
- }
+ initTree(nzNodes: NzTreeNode[]): void {
+ this.rootNodes = nzNodes;
+ this.expandedNodeList = [];
+ this.selectedNodeList = [];
+ this.halfCheckedNodeList = [];
+ this.checkedNodeList = [];
+ this.expandedNodeList = [];
+ this.matchedNodeList = [];
+ setTimeout(() => {
+ this.refreshCheckState(this.conductOption.isCheckStrictly);
+ });
+ }
+
+ getSelectedNode(): NzTreeNode | null {
+ return this.selectedNode;
+ }
+
+ /**
+ * get some list
+ */
+ getSelectedNodeList(): NzTreeNode[] {
+ return this.selectedNodeList;
+ }
+
+ /**
+ * return checked nodes
+ */
+ getCheckedNodeList(): NzTreeNode[] {
+ return this.conductCheck('check');
+ }
+
+ getHalfCheckedNodeList(): NzTreeNode[] {
+ return this.conductCheck('halfCheck');
+ }
+
+ /**
+ * return expanded nodes
+ */
+ getExpandedNodeList(): NzTreeNode[] {
+ return this.expandedNodeList;
+ }
+
+ /**
+ * return search matched nodes
+ */
+ getMatchedNodeList(): NzTreeNode[] {
+ return this.matchedNodeList;
+ }
+
+ // tslint:disable-next-line:no-any
+ isArrayOfNzTreeNode(value: any[]): boolean {
+ return value.every(item => item instanceof NzTreeNode);
}
- initTreeNodes(root: NzTreeNode[], defaultCheckedKeys: string[] = [], nzCheckStrictly: boolean = false): NzTreeNode[] {
- this.rootNodes = root;
- if (root.length > 0) {
- root.forEach((node) => {
- this.initCheckedStatus(node, defaultCheckedKeys, nzCheckStrictly);
+ /**
+ * reset selectedNodeList
+ */
+ calcSelectedKeys(selectedKeys: string[], nzNodes: NzTreeNode[], isMulti: boolean = false): void {
+ this.selectedNodeList = [];
+ const calc = (nodes: NzTreeNode[]) => {
+ nodes.forEach(node => {
+ if (isInArray(node.key, selectedKeys)) {
+ node.setSelected(true);
+ } else {
+ node.setSelected(false);
+ }
+ this.setSelectedNodeList(node, isMulti);
+ if (node.getChildren().length > 0) {
+ calc(node.getChildren());
+ }
});
- if (!nzCheckStrictly) {
- root.forEach((node) => {
- this.initParentNode(node);
- });
- // should reset node status
- }
- }
- return this.rootNodes;
+ };
+ calc(nzNodes);
+
}
/**
- * init checkBox state
+ * reset expandedNodeList
*/
- initParentNode(node: NzTreeNode): void {
- if (node.getChildren().length === 0) {
- // until root
- this.checkTreeNodeParents(node);
- } else {
- node.children.forEach((child) => {
- this.initParentNode(child);
+ calcExpandedKeys(expandedKeys: string[], nzNodes: NzTreeNode[]): void {
+ this.expandedNodeList = [];
+ const calc = (nodes: NzTreeNode[]) => {
+ nodes.forEach(node => {
+ if (isInArray(node.key, expandedKeys)) {
+ node.setExpanded(true);
+ this.setExpandedNodeList(node);
+ } else {
+ node.setExpanded(false);
+ }
+ if (node.getChildren().length > 0) {
+ calc(node.getChildren());
+ }
});
- }
+ };
+ calc(nzNodes);
}
/**
- * 1、children half checked
- * 2、children all checked, parent checked
- * 3、no children checked
+ * reset checkedNodeList
*/
- 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))) {
- if (!(parentNode.isDisabled || parentNode.isDisableCheckbox)) {
- parentNode.isChecked = true;
- parentNode.isAllChecked = true;
- parentNode.isHalfChecked = false;
+ calcCheckedKeys(checkedKeys: string[], nzNodes: NzTreeNode[], isCheckStrictly: boolean = false): void {
+ this.checkedNodeList = [];
+ this.halfCheckedNodeList = [];
+ const calc = (nodes: NzTreeNode[]) => {
+ nodes.forEach(node => {
+ if (isInArray(node.key, checkedKeys)) {
+ node.setChecked(true);
+ this.setCheckedNodeList(node);
+ } else {
+ node.setChecked(false);
}
- } else if (parentNode.children.some(child => child.isHalfChecked || child.isAllChecked)) {
- if (!(parentNode.isDisabled || parentNode.isDisableCheckbox)) {
- parentNode.isChecked = false;
- parentNode.isAllChecked = false;
- parentNode.isHalfChecked = true;
+ if (node.getChildren().length > 0) {
+ calc(node.getChildren());
}
- } else {
- parentNode.isChecked = false;
- parentNode.isAllChecked = false;
- parentNode.isHalfChecked = false;
- }
- this.checkTreeNodeParents(parentNode);
- }
+ });
+ };
+ calc(nzNodes);
+ // controlled state
+ this.refreshCheckState(isCheckStrictly);
}
- setSelectedNode(node: NzTreeNode | null): void {
- this.selectedNode = node;
+ /**
+ * set drag node
+ */
+ setSelectedNode(node?: NzTreeNode): void {
+ this.selectedNode = null;
+ if (node) {
+ this.selectedNode = node;
+ }
}
- getSelectedNode(): NzTreeNode | null {
- return this.selectedNode;
+ /**
+ * set node selected status
+ */
+ setNodeActive(node: NzTreeNode, isMultiple: boolean = false): void {
+ const isSelected = node.isSelected;
+ if (node.isDisabled) {
+ return;
+ }
+ if (!isMultiple) {
+ this.selectedNodeList.forEach(n => {
+ n.setSelected(false);
+ });
+ this.selectedNodeList = [];
+ }
+ node.setSelected(!isSelected);
+ this.setSelectedNodeList(node, isMultiple);
}
- // if node is clicked, add or remove node to select list
- setSelectedNodeList(node: NzTreeNode, isMultiple: boolean): void {
+ /**
+ * add or remove node to selectedNodeList
+ */
+ setSelectedNodeList(node: NzTreeNode, isMultiple: boolean = false): void {
+ const index = this.selectedNodeList.findIndex(n => node.key === n.key);
if (isMultiple) {
- const sIndex = this.selectedNodeList.findIndex(cNode => node.key === cNode.key);
- if (node.isSelected && sIndex === -1) {
+ if (node.isSelected && index === -1) {
this.selectedNodeList.push(node);
- } else if (sIndex > -1 && !node.isSelected) {
- this.selectedNodeList.splice(sIndex, 1);
}
} else {
- if (node.isSelected) {
+ if (node.isSelected && index === -1) {
this.selectedNodeList = [ node ];
- } else {
- this.selectedNodeList = [];
}
}
- }
-
- getSelectedNodeList(): NzTreeNode[] {
- return this.selectedNodeList;
+ if (!node.isSelected && index > -1) {
+ this.selectedNodeList.splice(index, 1);
+ }
}
/**
* merge checked nodes
*/
- setCheckedNodeListStrict(node: NzTreeNode): void {
- if (node.isChecked && this.checkedNodeList.findIndex(cNode => (node.key === cNode.key)) === -1) {
- this.checkedNodeList.push(node);
- } else if (!node.isChecked && this.checkedNodeList.findIndex(cNode => (node.key === cNode.key)) > -1) {
- // cancel checked
- this.checkedNodeList.splice(this.checkedNodeList.findIndex(cNode => (node.key === cNode.key)), 1);
+ setHalfCheckedNodeList(node: NzTreeNode): void {
+ const index = this.halfCheckedNodeList.findIndex(n => node.key === n.key);
+ if (node.isHalfChecked && index === -1) {
+ this.halfCheckedNodeList.push(node);
+ } else if (!node.isHalfChecked && index > -1) {
+ this.halfCheckedNodeList.splice(index, 1);
}
}
setCheckedNodeList(node: NzTreeNode): void {
- if (node.isChecked && this.checkedNodeList.findIndex(cNode => (node.key === cNode.key)) === -1) {
+ const index = this.checkedNodeList.findIndex(n => node.key === n.key);
+ if (node.isChecked && index === -1) {
this.checkedNodeList.push(node);
+ } else if (!node.isChecked && index > -1) {
+ this.checkedNodeList.splice(index, 1);
}
- const removeChild = (rNode: NzTreeNode) => {
- const rIndex = this.checkedNodeList.findIndex(cNode => (rNode.key === cNode.key));
- if (rIndex > -1) {
- this.checkedNodeList.splice(rIndex, 1);
- }
- rNode.children.forEach(child => {
- removeChild(child);
- });
- };
- // refresh tree nodes check state, merge child node checked
- this.rootNodes.forEach((rNode: NzTreeNode) => {
- const loopNode = (lNode: NzTreeNode) => {
- const cIndex = this.checkedNodeList.findIndex(cNode => (lNode.key === cNode.key));
- if (lNode.isChecked) {
- if (cIndex === -1) {
- this.checkedNodeList.push(lNode);
- }
- // reset child state
- lNode.children.forEach((child) => {
- removeChild(child);
- });
- } else {
- if (cIndex > -1) {
- this.checkedNodeList.splice(cIndex, 1);
- }
- lNode.children.forEach(child => {
- loopNode(child);
- });
- }
- };
- loopNode(rNode);
- });
- }
-
- /**
- * return checked nodes
- */
- getCheckedNodeList(): NzTreeNode[] {
- return this.checkedNodeList;
}
/**
- * return half checked nodes
- * returns {NzTreeNode[]}
+ * conduct checked keys
*/
- getHalfCheckedNodeList(): NzTreeNode[] {
- this.halfCheckedNodeList = [];
- this.rootNodes.forEach((rNode: NzTreeNode) => {
- const loopNode = (lNode: NzTreeNode) => {
- const cIndex = this.halfCheckedNodeList.findIndex(cNode => (lNode.key === cNode.key));
- if (lNode.isHalfChecked) {
- if (cIndex === -1) {
- this.halfCheckedNodeList.push(lNode);
+ conductCheck(type: string = 'check'): NzTreeNode[] {
+ const checkedNodeList = [];
+ const loop = (node: NzTreeNode) => {
+ switch (type) {
+ case 'check':
+ if (node.isChecked) {
+ checkedNodeList.push(node);
}
- // reset child state
- lNode.children.forEach((child) => {
- loopNode(child);
- });
- }
- };
- loopNode(rNode);
+ if (!this.conductOption.isCheckStrictly) {
+ if (!node.isChecked) {
+ node.getChildren().forEach(child => {
+ loop(child);
+ });
+ }
+ } else {
+ node.getChildren().forEach(child => {
+ loop(child);
+ });
+ }
+ break;
+ case 'halfCheck':
+ if (!this.conductOption.isCheckStrictly) {
+ if (node.isHalfChecked) {
+ checkedNodeList.push(node);
+ node.getChildren().forEach(child => {
+ loop(child);
+ });
+ }
+ }
+ break;
+ }
+ };
+ this.rootNodes.forEach(node => {
+ loop(node);
});
- return this.halfCheckedNodeList;
+ return checkedNodeList;
}
/**
- * return search matched nodes
+ * set expanded nodes
*/
- getMatchedNodeList(): NzTreeNode[] {
- return this.matchedNodeList;
+ setExpandedNodeList(node: NzTreeNode): void {
+ if (node.isLeaf) {
+ return;
+ }
+ const index = this.expandedNodeList.findIndex(n => node.key === n.key);
+ if (node.isExpanded && index === -1) {
+ this.expandedNodeList.push(node);
+ } else if (!node.isExpanded && index > -1) {
+ this.expandedNodeList.splice(index, 1);
+ }
}
/**
- * keep selected state if isMultiple is true
+ * check state
+ * @param node
*/
- initNodeActive(node: NzTreeNode, isMultiple: boolean = false): void {
- if (node.isDisabled) {
+ refreshCheckState(isCheckStrictly: boolean = false): void {
+ if (isCheckStrictly) {
return;
}
- const isSelected = node.isSelected;
- if (!isMultiple) {
- this.rootNodes.forEach((child) => {
- this.resetNodeActive(child);
- });
- }
- node.isSelected = !isSelected;
- this.setSelectedNodeList(node, isMultiple);
- }
- // reset all nodes to unselected
- resetNodeActive(node: NzTreeNode): void {
- node.isSelected = false;
- node.children.forEach((child) => {
- this.resetNodeActive(child);
+ this.checkedNodeList.forEach(node => {
+ this.conduct(node);
});
}
+ conduct(node: NzTreeNode): void {
+ const isChecked = node.isChecked;
+ if (node) {
+ this.conductUp(node);
+ this.conductDown(node, isChecked);
+ }
+ }
+
/**
- * click checkbox
+ * 1、children half checked
+ * 2、children all checked, parent checked
+ * 3、no children checked
*/
- checkTreeNode(node: NzTreeNode): void {
- this.checkTreeNodeChildren(node, node.isChecked);
- this.checkTreeNodeParents(node);
+ conductUp(node: NzTreeNode): void {
+ const parentNode = node.getParentNode();
+ // 全禁用节点不选中
+ if (parentNode) {
+ if (!isCheckDisabled(parentNode)) {
+ if (parentNode.getChildren().every(child => isCheckDisabled(child) || (!child.isHalfChecked && child.isChecked))) {
+ parentNode.setChecked(true);
+ } else if (parentNode.getChildren().some(child => child.isHalfChecked || child.isChecked)) {
+ parentNode.setChecked(false, true);
+ } else {
+ parentNode.setChecked(false);
+ }
+ }
+ this.setHalfCheckedNodeList(parentNode);
+ this.conductUp(parentNode);
+ }
}
/**
* reset child check state
*/
- checkTreeNodeChildren(node: NzTreeNode, value: boolean): void {
- if (!node.isDisabled && !node.isDisableCheckbox) {
- node.isChecked = value;
- node.isAllChecked = value;
- if (node.isChecked) {
- node.isHalfChecked = false;
- }
- }
- // 遍历全部子节点
- for (const n of node.children) {
- this.checkTreeNodeChildren(n, value);
+ conductDown(node: NzTreeNode, value: boolean): void {
+ if (!isCheckDisabled(node)) {
+ node.setChecked(value);
+ node.children.forEach(n => {
+ this.conductDown(n, value);
+ });
}
}
/**
- * search & expand node
+ * search value & expand node
+ * should add expandlist
*/
searchExpand(value: string): void {
this.matchedNodeList = [];
- if (!value) {
+ if (!isNotNil(value)) {
return;
}
- const loopParent = (node: NzTreeNode) => {
+ // to reset expandedNodeList
+ this.expandedNodeList = [];
+ const expandParent = (p: NzTreeNode) => {
// expand parent node
- if (node.getParentNode()) {
- node.getParentNode().isExpanded = true;
- loopParent(node.getParentNode());
+ if (p.getParentNode()) {
+ p.getParentNode().setExpanded(true);
+ this.setExpandedNodeList(p.getParentNode());
+ expandParent(p.getParentNode());
}
};
- const loopChild = (node: NzTreeNode) => {
- if (value && node.title.includes(value)) {
+ const searchChild = (n: NzTreeNode) => {
+ if (value && n.title.includes(value)) {
// match the node
- this.matchedNodeList.push(node);
+ this.matchedNodeList.push(n);
// expand parentNode
- loopParent(node);
+ expandParent(n);
} else {
- node.isExpanded = false;
+ n.setExpanded(false);
+ this.setExpandedNodeList(n);
}
- node.children.forEach(cNode => {
- loopChild(cNode);
+ n.children.forEach(g => {
+ searchChild(g);
});
};
- this.rootNodes.forEach(node => {
- loopChild(node);
+ this.rootNodes.forEach(child => {
+ searchChild(child);
});
}
+ /**
+ * drag event
+ */
+ refreshDragNode(node: NzTreeNode): void {
+ if (node.getChildren().length === 0) {
+ // until root
+ this.conductUp(node);
+ } else {
+ node.children.forEach((child) => {
+ this.refreshDragNode(child);
+ });
+ }
+ }
+
+ // reset node level
+ resetNodeLevel(node: NzTreeNode): void {
+ if (node.getParentNode()) {
+ node.level = node.getParentNode().level + 1;
+ } else {
+ node.level = 0;
+ }
+ for (const child of node.getChildren()) {
+ this.resetNodeLevel(child);
+ }
+ }
+
+ calcDropPosition(event: DragEvent): number {
+ const { clientY } = event;
+ // to fix firefox undefined
+ const { top, bottom, height } = event.srcElement ? event.srcElement.getBoundingClientRect() : (event.target as Element).getBoundingClientRect();
+ const des = Math.max(height * this.DRAG_SIDE_RANGE, this.DRAG_MIN_GAP);
+
+ if (clientY <= top + des) {
+ return -1;
+ } else if (clientY >= bottom - des) {
+ return 1;
+ }
+
+ return 0;
+ }
+
/**
* drop
* 0: inner -1: pre 1: next
@@ -330,7 +433,9 @@ export class NzTreeService {
const tIndex = dragPos === 1 ? 1 : 0;
if (targetParent) {
targetParent.addChildren([ this.selectedNode ], targetParent.children.indexOf(targetNode) + tIndex);
- this.resetNodeLevel(this.selectedNode.getParentNode());
+ if (this.selectedNode.getParentNode()) {
+ this.resetNodeLevel(this.selectedNode.getParentNode());
+ }
} else {
const targetIndex = this.rootNodes.indexOf(targetNode) + tIndex;
// 根节点插入
@@ -342,36 +447,10 @@ export class NzTreeService {
}
// flush all nodes
this.rootNodes.forEach((child) => {
- this.initParentNode(child);
+ this.refreshDragNode(child);
});
}
- // reset node level
- resetNodeLevel(node: NzTreeNode): void {
- if (node.getParentNode()) {
- node.level = node.getParentNode().level + 1;
- } else {
- node.level = 0;
- }
- for (const child of node.getChildren()) {
- this.resetNodeLevel(child);
- }
- }
-
- calcDropPosition(e: DragEvent): number {
- const { clientY } = e;
- const { top, bottom, height } = e.srcElement.getBoundingClientRect();
- const des = Math.max(height * this.DRAG_SIDE_RANGE, this.DRAG_MIN_GAP);
-
- if (clientY <= top + des) {
- return -1;
- } else if (clientY >= bottom - des) {
- return 1;
- }
-
- return 0;
- }
-
/**
* emit Structure
* eventName
@@ -395,15 +474,30 @@ export class NzTreeService {
Object.assign(emitStructure, { 'dragNode': this.getSelectedNode() });
break;
case 'click':
+ case 'dblclick':
+ // TODO: Deprecated
Object.assign(emitStructure, { 'selectedKeys': this.getSelectedNodeList() });
+ Object.assign(emitStructure, { 'nodes': this.getSelectedNodeList() });
+ Object.assign(emitStructure, { 'keys': this.getSelectedNodeList().map(n => n.key) });
break;
case 'check':
+ // TODO: Deprecated
Object.assign(emitStructure, { 'checkedKeys': this.getCheckedNodeList() });
+ Object.assign(emitStructure, { 'nodes': this.getCheckedNodeList() });
+ Object.assign(emitStructure, { 'keys': this.getCheckedNodeList().map(n => n.key) });
break;
case 'search':
+ // TODO: Deprecated
Object.assign(emitStructure, { 'matchedKeys': this.getMatchedNodeList() });
+ Object.assign(emitStructure, { 'nodes': this.getMatchedNodeList() });
+ Object.assign(emitStructure, { 'keys': this.getMatchedNodeList().map(n => n.key) });
+ break;
+ case 'expand':
+ Object.assign(emitStructure, { 'nodes': this.getExpandedNodeList() });
+ Object.assign(emitStructure, { 'keys': this.getExpandedNodeList().map(n => n.key) });
break;
}
return emitStructure;
}
+
}
diff --git a/components/tree/nz-tree.spec.ts b/components/tree/nz-tree.spec.ts
index 1fa19aca9b6..df91d73cea9 100644
--- a/components/tree/nz-tree.spec.ts
+++ b/components/tree/nz-tree.spec.ts
@@ -1,298 +1,334 @@
import { Component, ViewChild } from '@angular/core';
-import { async, fakeAsync, tick, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, fakeAsync, tick, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { By } from '@angular/platform-browser';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { of, Observable } from 'rxjs';
-import { dispatchMouseEvent, dispatchTouchEvent } from '../core/testing/dispatch-events';
+import { dispatchMouseEvent, dispatchTouchEvent } from '../core/testing';
import { NzFormatBeforeDropEvent, NzFormatEmitEvent } from './interface';
import { NzTreeNode } from './nz-tree-node';
import { NzTreeComponent } from './nz-tree.component';
import { NzTreeModule } from './nz-tree.module';
import { NzTreeService } from './nz-tree.service';
-describe('tree component test', () => {
+describe('nz-tree', () => {
let treeInstance;
- let fixture: ComponentFixture<{}>;
+ let treeElement: HTMLElement;
+ let component;
+ let fixture;
let treeService: NzTreeService;
-
describe('basic tree', () => {
- let treeElement: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports : [ NzTreeModule, NoopAnimationsModule, FormsModule, ReactiveFormsModule ],
- declarations: [ NzDemoBasicTreeComponent ]
+ declarations: [ NzTestTreeBasicControlledComponent ]
}).compileComponents();
- }));
-
- beforeEach(async(() => {
- fixture = TestBed.createComponent(NzDemoBasicTreeComponent);
+ fixture = TestBed.createComponent(NzTestTreeBasicControlledComponent);
+ component = fixture.componentInstance;
fixture.detectChanges();
treeInstance = fixture.debugElement.componentInstance;
treeElement = fixture.debugElement.query(By.directive(NzTreeComponent)).nativeElement;
}));
-
it('should create', () => {
- expect(treeInstance).toBeTruthy();
+ expect(component).toBeDefined();
});
- it('should className correct', fakeAsync(() => {
- fixture.detectChanges();
- tick(100);
- fixture.detectChanges();
- const allSelectedKeys = treeElement.querySelectorAll('.ant-tree-node-selected');
- expect(allSelectedKeys[ 0 ].getAttribute('title')).toEqual('child1');
- expect(allSelectedKeys[ 1 ].getAttribute('title')).toEqual('child1.1');
- expect(treeInstance.treeComponent.getSelectedNodeList().length).toEqual(2);
- // checked(child1 has disabled nodes)
- const allCheckedKeys = treeElement.querySelectorAll('.ant-tree-checkbox-checked');
- expect(allCheckedKeys.length).toEqual(2);
- // merged to one node
+ it('should set nzDefaultXXX correctly', fakeAsync(() => {
+ fixture.detectChanges();
+ // checked
expect(treeInstance.treeComponent.getCheckedNodeList().length).toEqual(1);
+ expect(treeInstance.treeComponent.getCheckedNodeList()[ 0 ].title).toEqual('0-0-0');
+ // half expanded
+ expect(treeInstance.treeComponent.getHalfCheckedNodeList().length).toEqual(1);
+ expect(treeInstance.treeComponent.getHalfCheckedNodeList()[ 0 ].title).toEqual('0-0');
// expanded
- const allExpandedKeys = treeElement.querySelectorAll('.ant-tree-switcher_open');
- expect(allExpandedKeys.length).toEqual(2);
- }));
+ expect(treeInstance.treeComponent.getExpandedNodeList().length).toEqual(2);
+ // selected
+ expect(treeInstance.treeComponent.getSelectedNodeList().length).toEqual(1);
+ expect(treeInstance.treeComponent.getSelectedNodeList()[ 0 ].title).toEqual('0-0-0-0');
- it('click should response correctly', fakeAsync(() => {
+ // won't affect
+ treeInstance.defaultExpandedKeys = [];
fixture.detectChanges();
- tick(100);
+ tick();
fixture.detectChanges();
- const clickSpy = spyOn(treeInstance, 'onClick');
- // click child1
- let targetNode = treeElement.querySelectorAll('li')[ 1 ];
- expect(targetNode.querySelectorAll('.ant-tree-node-selected').length).toEqual(2);
- dispatchMouseEvent(targetNode, 'click');
- fixture.detectChanges();
- // cancel selected
- targetNode = treeElement.querySelectorAll('li')[ 1 ];
- expect(targetNode.querySelectorAll('.ant-tree-node-selected').length).toEqual(1);
- expect(clickSpy).toHaveBeenCalled();
- expect(clickSpy).toHaveBeenCalledTimes(1);
+ expect(treeInstance.treeComponent.getExpandedNodeList().length).toEqual(2);
+
}));
- it('dblclick/contextmenu should response correctly', fakeAsync(() => {
+
+ it('test unCorrectly ngModel', () => {
fixture.detectChanges();
- tick(100);
+ // TODO
+ // unsupported type, will console `ngModel only accepts an array and should be not empty`
+ treeInstance.nodes = 'string';
fixture.detectChanges();
- const clickSpy = spyOn(treeInstance, 'onClick');
- const dblClickSpy = spyOn(treeInstance, 'onDblClick');
- const contextMenuSpy = spyOn(treeInstance, 'onContextMenu');
- // detect changes
+ });
+
+ it('test new NzTreeNode of nzData', fakeAsync(() => {
fixture.detectChanges();
- // dblclick child1
- let targetNode = treeElement.querySelectorAll('li')[ 1 ];
- dispatchMouseEvent(targetNode, 'dblclick');
+ treeInstance.nodes = [ {
+ title : '0-0',
+ key : '0-0',
+ expanded: true,
+ children: [ {
+ title : '0-0-0',
+ key : '0-0-0',
+ expanded: true,
+ checked : true,
+ children: [
+ { title: '0-0-0-0', key: '0-0-0-0', isLeaf: true },
+ { title: '0-0-0-1', key: '0-0-0-1', isLeaf: true },
+ { title: '0-0-0-2', key: '0-0-0-2', isLeaf: true }
+ ]
+ }, {
+ title : '0-0-1',
+ key : '0-0-1',
+ selected: true,
+ children: [
+ { title: '0-0-1-0', key: '0-0-1-0', isLeaf: true },
+ { title: '0-0-1-1', key: '0-0-1-1', isLeaf: true },
+ { title: '0-0-1-2', key: '0-0-1-2', isLeaf: true }
+ ]
+ }, {
+ title : '0-0-2',
+ key : '0-0-2',
+ isLeaf: true
+ } ]
+ }, {
+ title : '0-1',
+ key : '0-1',
+ children: [
+ { title: '0-1-0-0', key: '0-1-0-0', isLeaf: true },
+ { title: '0-1-0-1', key: '0-1-0-1', isLeaf: true },
+ { title: '0-1-0-2', key: '0-1-0-2', isLeaf: true }
+ ]
+ } ].map(v => {
+ return (new NzTreeNode(v));
+ });
fixture.detectChanges();
- // cancel selected
- expect(clickSpy).toHaveBeenCalledTimes(0);
- // dblclick
- expect(dblClickSpy).toHaveBeenCalled();
- expect(dblClickSpy).toHaveBeenCalledTimes(1);
- // contextmenu
- targetNode = treeElement.querySelectorAll('li')[ 1 ];
- dispatchMouseEvent(targetNode, 'contextmenu');
- expect(contextMenuSpy).toHaveBeenCalled();
- expect(contextMenuSpy).toHaveBeenCalledTimes(1);
+ tick(1000);
+ fixture.detectChanges();
+ // reset node will clear default value except checked nodes list
+ expect(treeInstance.treeComponent.getSelectedNodeList().length).toEqual(1);
+ expect(treeInstance.treeComponent.getExpandedNodeList().length).toEqual(2);
+ expect(treeInstance.treeComponent.getMatchedNodeList().length).toEqual(0);
+ // // checked nodes no effect
+ expect(treeInstance.treeComponent.getCheckedNodeList().length).toEqual(1);
+ expect(treeInstance.treeComponent.getCheckedNodeList()[ 0 ].title).toEqual('0-0-0');
+
+ expect(treeInstance.treeComponent.getHalfCheckedNodeList().length).toEqual(1);
+ expect(treeInstance.treeComponent.getHalfCheckedNodeList()[ 0 ].title).toEqual('0-0');
}));
- it('check/expand should response correctly', fakeAsync(() => {
- fixture.detectChanges();
- tick(100);
+ it('test click event', fakeAsync(() => {
fixture.detectChanges();
- const checkSpy = spyOn(treeInstance, 'onCheck');
- const expandSpy = spyOn(treeInstance, 'onExpand');
- // detect changes
+ const clickSpy = spyOn(treeInstance, 'nzEvent');
+ // click 0-0-0 to select
+ let targetNode = treeElement.querySelectorAll('nz-tree-node')[ 1 ];
+ dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
- // 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');
+ // 0-0-0 / 0-0-0-0 are selected
+ expect(treeElement.querySelectorAll('.ant-tree-node-selected').length).toEqual(2);
+ expect(treeInstance.treeComponent.getSelectedNodeList().length).toEqual(2);
+ expect(clickSpy).toHaveBeenCalledTimes(1);
+ // cancel 0-0-0 selected
dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
- targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 0 ];
- // 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');
- // cancel checked status
+ expect(treeInstance.treeComponent.getSelectedNodeList().length).toEqual(1);
+ expect(clickSpy).toHaveBeenCalledTimes(2);
+
+ // double click 0-0-0, only response once
+ targetNode = treeElement.querySelectorAll('nz-tree-node')[ 1 ];
+ dispatchMouseEvent(targetNode, 'dblclick');
+ fixture.detectChanges();
+ // 0-0-0-0 are selected
+ expect(treeElement.querySelectorAll('.ant-tree-node-selected').length).toEqual(1);
+ expect(treeInstance.treeComponent.getSelectedNodeList().length).toEqual(1);
+ expect(clickSpy).toHaveBeenCalledTimes(3); // will detect dblclick
+
+ // click disabled node
+ targetNode = treeElement.querySelectorAll('nz-tree-node')[ treeElement.querySelectorAll('nz-tree-node').length - 1 ];
dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
+ expect(treeElement.querySelectorAll('.ant-tree-node-selected').length).toEqual(1);
- // click node grandchild1.2.1 to test disabled node.(won't effect parent node)
- targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 4 ];
+ // set nzMultiple to false, click 0-0-0-0 will just active one node
+ treeInstance.multiple = false;
+ fixture.detectChanges();
+ targetNode = treeElement.querySelectorAll('nz-tree-node')[ 0 ];
dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
- expect(treeInstance.treeComponent.getCheckedNodeList().length).toEqual(1);
+ expect(treeElement.querySelectorAll('.ant-tree-node-selected').length).toEqual(1);
+ expect(treeInstance.treeComponent.getSelectedNodeList().length).toEqual(1);
+ expect(treeInstance.treeComponent.getSelectedNodeList()[ 0 ].title).toEqual('0-0');
+
+ // cancel selected
+ targetNode = treeElement.querySelectorAll('nz-tree-node')[ 0 ];
dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
+ expect(treeElement.querySelectorAll('.ant-tree-node-selected').length).toEqual(0);
+ expect(treeInstance.treeComponent.getSelectedNodeList().length).toEqual(0);
+ }));
- expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(0);
- expect(treeInstance.treeComponent.getCheckedNodeList().length).toEqual(0);
- // test half checked nodes, click child1.1, just root1 halfchecked(child1 is full checked)
- targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 2 ];
+ it('test expand event', fakeAsync(() => {
+ fixture.detectChanges();
+ // expand 0-0,now 3 nodes expanded
+ const targetNode = treeElement.querySelectorAll('.ant-tree-switcher')[ 0 ];
+ expect(fixture.componentInstance.treeComponent.getExpandedNodeList().length).toEqual(2);
dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
- expect(treeInstance.treeComponent.getHalfCheckedNodeList().length).toEqual(1);
- // // click disabled node
- targetNode = treeElement.querySelector('.ant-tree-checkbox-disabled');
+ expect(fixture.componentInstance.treeComponent.getExpandedNodeList().length).toEqual(3);
+ expect(treeElement.querySelectorAll('.ant-tree-switcher_open').length).toEqual(3);
+ }));
+
+ it('test check event', fakeAsync(() => {
+ fixture.detectChanges();
+ // uncheck 0-0-0
+ let targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 1 ];
+ expect(fixture.componentInstance.treeComponent.getCheckedNodeList().length).toEqual(1);
dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
- expect(targetNode.classList).toContain('ant-tree-checkbox-disabled');
+ expect(fixture.componentInstance.treeComponent.getCheckedNodeList().length).toEqual(0);
+ expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(0);
- // expand node
- targetNode = treeElement.querySelectorAll('.ant-tree-switcher_close')[ 0 ];
+ // check 0-0-0, will make 0-0 indeterminate
+ targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 1 ];
dispatchMouseEvent(targetNode, 'click');
+ tick(300);
fixture.detectChanges();
- expect(targetNode.classList).toContain('ant-tree-switcher_open');
- expect(expandSpy).toHaveBeenCalled();
- expect(expandSpy).toHaveBeenCalledTimes(1);
+ expect(fixture.componentInstance.treeComponent.getCheckedNodeList().length).toEqual(1);
+ expect(fixture.componentInstance.treeComponent.getHalfCheckedNodeList().length).toEqual(1);
}));
- it('should className correct showline/showexpand/expandall', fakeAsync(() => {
- treeInstance.showLine = true;
+ it('test check event with nzCheckStrictly', fakeAsync(() => {
fixture.detectChanges();
- tick(100);
+ treeInstance.checkStrictly = true;
+ treeInstance.nodes = [
+ {
+ title : 'parent',
+ key : '0',
+ children: [
+ {
+ title : 'child 1',
+ key : '0-0',
+ isLeaf: true
+ },
+ {
+ title : 'child 2',
+ key : '0-1',
+ isLeaf: true
+ }
+ ]
+ }
+ ];
fixture.detectChanges();
- expect(treeElement.querySelector('ul').classList).toContain('ant-tree-show-line');
- // hide expand icon
- expect(treeElement.querySelectorAll('.ant-tree-switcher').length).toBeGreaterThan(0);
- treeInstance.showExpand = false;
+ tick();
fixture.detectChanges();
- expect(treeElement.querySelectorAll('.ant-tree-switcher').length).toEqual(0);
- // expandAll
- treeInstance.expandDefault = true;
+ // check node will not affect other nodes
+ let targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 0 ];
+ dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
- }));
+ expect(fixture.componentInstance.treeComponent.getCheckedNodeList().length).toEqual(1);
+ expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(1);
- it('search value', () => {
- const searchSpy = spyOn(treeInstance, 'onSearch');
- treeInstance.searchValue = 'grand';
+ targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 1 ];
+ dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
- expect(treeElement.querySelectorAll('.font-highlight').length).toEqual(5);
- expect(searchSpy).toHaveBeenCalled();
- expect(searchSpy).toHaveBeenCalledTimes(1);
- });
- });
+ expect(fixture.componentInstance.treeComponent.getCheckedNodeList().length).toEqual(2);
+ expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(2);
- describe('async tree', () => {
- treeInstance = null;
- fixture = null;
- let treeElement: HTMLElement;
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- imports : [ NzTreeModule, NoopAnimationsModule, FormsModule, ReactiveFormsModule ],
- declarations: [ NzDemoAsyncTreeComponent ]
- }).compileComponents();
}));
- beforeEach(fakeAsync(() => {
- fixture = TestBed.createComponent(NzDemoAsyncTreeComponent);
- treeInstance = fixture.debugElement.componentInstance;
- treeElement = fixture.debugElement.query(By.directive(NzTreeComponent)).nativeElement;
+ it('test contextmenu event', fakeAsync(() => {
fixture.detectChanges();
+ const clickSpy = spyOn(treeInstance, 'nzEvent');
+ // contextmenu 0-0-0
+ const targetNode = treeElement.querySelectorAll('nz-tree-node')[ 1 ];
+ dispatchMouseEvent(targetNode, 'contextmenu');
+ fixture.detectChanges();
+ expect(clickSpy).toHaveBeenCalledTimes(1);
}));
- it('should create', () => {
- expect(treeInstance).toBeTruthy();
- });
-
- it('should add children', () => {
- const expandSpy = spyOn(treeInstance, 'onExpand');
- // detect changes
+ it('test disabled node check event', fakeAsync(() => {
fixture.detectChanges();
- // init
- expect(treeElement.querySelectorAll('.ant-tree-switcher').length).toEqual(3);
- // click expand, test can not excute add children
- const targetNode = treeElement.querySelectorAll('.ant-tree-switcher')[ 0 ];
+ const clickSpy = spyOn(treeInstance, 'nzEvent');
+ // contextmenu 0-0-0
+ const targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ treeElement.querySelectorAll('li').length - 1 ];
dispatchMouseEvent(targetNode, 'click');
fixture.detectChanges();
- expect(expandSpy).toHaveBeenCalled();
- expect(expandSpy).toHaveBeenCalledTimes(1);
- });
- });
-
- describe('test node', () => {
- let treeNode: NzTreeNode;
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- imports: [ NzTreeModule ]
- }).compileComponents();
+ expect(clickSpy).toHaveBeenCalledTimes(0);
}));
- beforeEach(fakeAsync(() => {
- treeNode = new NzTreeNode({
- title : 'root1',
- key : '1001',
- children: []
- });
+ it('test expand all node', fakeAsync(() => {
+ fixture.detectChanges();
+ fixture.componentInstance.expandAll = true;
+ tick();
+ fixture.detectChanges();
+ // all parent node will be expanded
+ expect(fixture.componentInstance.treeComponent.getExpandedNodeList().length).toEqual(4);
}));
- it('should create', () => {
- expect(treeNode).toBeDefined();
- });
-
- it('should add children', () => {
- // add json array
- treeNode.addChildren([
- {
- title: 'childAdd-1',
- key : '10031-' + (new Date()).getTime()
- },
- {
- title : 'childAdd-2',
- key : '10032-' + (new Date()).getTime(),
- isLeaf: true
- } ]);
- expect(treeNode.getChildren().length).toEqual(2);
- // add NzTreeNode
- treeNode.clearChildren();
- const newNode = new NzTreeNode({
- title: 'childAdd-1',
- key : '100001'
- });
- treeNode.addChildren([ newNode ]);
- expect(treeNode.getChildren().length).toEqual(1);
- expect(treeNode.getChildren()[ 0 ].title).toEqual('childAdd-1');
- });
+ it('test search value', fakeAsync(() => {
+ fixture.detectChanges();
+ fixture.componentInstance.searchValue = '0-0';
+ fixture.detectChanges();
+ // matched node's parent node will be expanded
+ expect(fixture.componentInstance.treeComponent.getExpandedNodeList().length).toEqual(4);
+ expect(fixture.componentInstance.treeComponent.getMatchedNodeList().length).toEqual(11);
+ expect(treeElement.querySelectorAll('.font-highlight').length).toEqual(11);
+ }));
- it('add children if node is leaf', () => {
- treeNode = new NzTreeNode({
- title : 'root1',
- key : '1001',
- isLeaf: true
- });
- treeNode.addChildren([ {
- title: 'childAdd-1',
- key : '100001'
+ it('test async loading', fakeAsync(() => {
+ fixture.detectChanges();
+ fixture.componentInstance.asyncData = true;
+ treeInstance.nodes = [
+ { title: 'Expand to load', key: '0' },
+ { title: 'Expand to load', key: '1' },
+ { title: 'Tree Node', key: '2', isLeaf: true }
+ ];
+ fixture.detectChanges();
+ tick();
+ fixture.detectChanges();
+ let targetNode = treeElement.querySelectorAll('.ant-tree-switcher')[ 0 ];
+ dispatchMouseEvent(targetNode, 'click');
+ tick();
+ fixture.detectChanges();
+ expect(treeElement.querySelectorAll('.ant-tree-treenode-loading').length).toEqual(1);
+ expect(treeElement.querySelectorAll('.ant-tree-switcher_open').length).toEqual(1);
+ expect(fixture.componentInstance.treeComponent.getExpandedNodeList().length).toEqual(1);
+ // add children to clear loading state
+ fixture.componentInstance.treeComponent.getExpandedNodeList()[ 0 ].addChildren([ {
+ title: 'Child Node',
+ key : `0-0`
} ]);
- expect(treeNode.getChildren().length).toEqual(0);
- });
+ fixture.detectChanges();
+ expect(treeElement.querySelectorAll('.ant-tree-treenode-loading').length).toEqual(0);
+ expect(fixture.componentInstance.treeComponent.getExpandedNodeList().length).toEqual(1);
- it('init node with children', () => {
- treeNode = new NzTreeNode({
- title : 'root1',
- key : '1001',
- checked : true,
- children: [ {
- title: 'childAdd-1',
- key : '100001'
- } ]
- });
- expect(treeNode.getChildren().length).toEqual(1);
- expect(treeNode.getChildren()[ 0 ].isChecked).toEqual(true);
- });
+ // add nzTreeNode children to clear loading state
+ targetNode = treeElement.querySelectorAll('.ant-tree-switcher')[ 2 ];
+ dispatchMouseEvent(targetNode, 'click');
+ tick();
+ fixture.detectChanges();
+ // getExpandedNodeList return ['0', '1']
+ expect(fixture.componentInstance.treeComponent.getExpandedNodeList().length).toEqual(2);
+ expect(treeElement.querySelectorAll('.ant-tree-treenode-loading').length).toEqual(1);
+ fixture.componentInstance.treeComponent.getExpandedNodeList()[ 1 ].addChildren([ new NzTreeNode({
+ title: 'Child Node',
+ key : `1-0`
+ }) ]);
+ fixture.detectChanges();
+ expect(treeElement.querySelectorAll('.ant-tree-treenode-loading').length).toEqual(0);
+ expect(treeElement.querySelectorAll('.ant-tree-switcher_open').length).toEqual(2);
+ expect(fixture.componentInstance.treeComponent.getExpandedNodeList().length).toEqual(2);
+ }));
});
describe('test draggable node', () => {
- let treeElement: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports : [ NzTreeModule, NoopAnimationsModule, FormsModule, ReactiveFormsModule ],
- declarations: [ NzDemoDraggableTreeComponent ],
+ declarations: [ NzTestTreeDraggableComponent ],
providers : [
NzTreeService
]
@@ -300,18 +336,19 @@ describe('tree component test', () => {
}));
beforeEach(async(() => {
- fixture = TestBed.createComponent(NzDemoDraggableTreeComponent);
+ fixture = TestBed.createComponent(NzTestTreeDraggableComponent);
+ component = fixture.componentInstance;
+ treeService = fixture.componentInstance.treeComponent.nzTreeService;
+ fixture.detectChanges();
treeInstance = fixture.debugElement.componentInstance;
treeElement = fixture.debugElement.query(By.directive(NzTreeComponent)).nativeElement;
- fixture.detectChanges();
}));
it('should create', () => {
expect(treeInstance).toBeTruthy();
});
- it('drag event', fakeAsync(() => {
- fixture.detectChanges();
- tick(100);
+
+ it('test drag event', fakeAsync(() => {
fixture.detectChanges();
const dragStartSpy = spyOn(treeInstance, 'onDragStart');
const dragEnterSpy = spyOn(treeInstance, 'onDragEnter');
@@ -319,405 +356,224 @@ describe('tree component test', () => {
const dragLeaveSpy = spyOn(treeInstance, 'onDragLeave');
const dropSpy = spyOn(treeInstance, 'onDrop');
const dragEndSpy = spyOn(treeInstance, 'onDragEnd');
-
- let dragNode = treeElement.querySelector('[title=root3]'); // root3
- let dropNode = treeElement.querySelector('[title=root1]'); // root1
- let passNode = treeElement.querySelector('[title=root2]'); // root2
+ let dragNode = treeElement.querySelector('[title=\'0-1\']');
+ let dropNode = treeElement.querySelector('[title=\'0-0\']');
+ let passNode = treeElement.querySelector('[title=\'0-0-0\']');
dispatchTouchEvent(dragNode, 'dragstart');
- dispatchTouchEvent(passNode, 'dragenter');
+ dispatchTouchEvent(dropNode, 'dragenter');
fixture.detectChanges();
+
// drag - dragenter
- dragNode = treeElement.querySelector('[title=root3]'); // root3
- passNode = treeElement.querySelector('[title=root2]'); // root2
+ dragNode = treeElement.querySelector('[title=\'0-1\']');
+ dropNode = treeElement.querySelector('[title=\'0-0\']');
expect(dragNode.previousElementSibling.classList).toContain('ant-tree-switcher_close');
- expect(passNode.previousElementSibling.classList).toContain('ant-tree-switcher_open');
+ expect(dropNode.previousElementSibling.classList).toContain('ant-tree-switcher_open');
expect(dragStartSpy).toHaveBeenCalledTimes(1);
expect(dragEnterSpy).toHaveBeenCalledTimes(1);
+
// dragover
dispatchTouchEvent(passNode, 'dragover');
fixture.detectChanges();
- passNode = treeElement.querySelector('[title=root2]'); // root2
+ passNode = treeElement.querySelector('[title=\'0-0-0\']');
expect(passNode.parentElement.classList).toContain('drag-over');
expect(dragOverSpy).toHaveBeenCalledTimes(1);
+
// dragleave
dispatchTouchEvent(passNode, 'dragleave');
fixture.detectChanges();
- passNode = treeElement.querySelector('[title=root2]'); // root2
+ passNode = treeElement.querySelector('[title=\'0-0-0\']');
expect(passNode.parentElement.classList.contains('drag-over')).toEqual(false);
expect(dragLeaveSpy).toHaveBeenCalledTimes(1);
- // drop root3 to root1
- dispatchTouchEvent(dropNode, 'dragover');
+
+ // drop 0-1 to 0-0
dispatchTouchEvent(dropNode, 'drop');
fixture.detectChanges();
+ dropNode = treeElement.querySelector('[title=\'0-0\']');
expect(dropSpy).toHaveBeenCalledTimes(1);
- dropNode = treeElement.querySelector('[title=root1]');
- expect(dropNode.parentElement.querySelector('[title=root3]')).toBeDefined();
+ expect(dropNode.parentElement.querySelector('[title=\'0-1\']')).toBeDefined();
+
// dragend
dispatchTouchEvent(dropNode, 'dragend');
fixture.detectChanges();
expect(dragEndSpy).toHaveBeenCalledTimes(1);
- }));
- it('drag event canDrop', () => {
- treeInstance.beforeDrop = (arg: NzFormatBeforeDropEvent): Observable => {
- return of(true);
- };
- fixture.detectChanges();
- const dropSpy = spyOn(treeInstance, 'onDrop');
-
- const dragNode = treeElement.querySelector('[title=root3]'); // root3
- let dropNode = treeElement.querySelector('[title=root1]'); // root1
+ // drag 0-0 child node to 0-1
+ dragNode = treeElement.querySelector('[title=\'0-0-0\']');
+ dropNode = treeElement.querySelector('[title=\'0-1\']');
dispatchTouchEvent(dragNode, 'dragstart');
- fixture.detectChanges();
- // drop root3 to root1
+ dispatchTouchEvent(dropNode, 'dragover');
dispatchTouchEvent(dropNode, 'drop');
fixture.detectChanges();
- expect(dropSpy).toHaveBeenCalledTimes(1);
- dropNode = treeElement.querySelector('[title=root1]');
- expect(dropNode.parentElement.querySelector('[title=root3]')).toBeDefined();
- });
- });
-
- describe('test service', () => {
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- imports : [ NzTreeModule, NoopAnimationsModule, FormsModule, ReactiveFormsModule ],
- declarations: [ NzDemoDraggableTreeComponent ],
- providers : [
- NzTreeService
- ]
- }).compileComponents();
+ dropNode = treeElement.querySelector('[title=\'0-1\']');
+ expect(dropSpy).toHaveBeenCalledTimes(2);
+ expect(dropNode.parentElement.querySelector('[title=\'0-0-0\']')).toBeDefined();
}));
- beforeEach(() => {
- fixture = TestBed.createComponent(NzDemoDraggableTreeComponent);
- treeInstance = fixture.debugElement.componentInstance;
- treeService = treeInstance.nzTreeService;
- treeService.initTreeNodes(treeInstance.nodes);
- });
- it('test service - setSelectedNodeList', () => {
- const selectedNode = treeService.rootNodes[ 0 ];
- // node is not selected
- treeService.setSelectedNodeList(selectedNode, false);
- // node is already selected
- selectedNode.isSelected = true;
- treeService.setSelectedNodeList(selectedNode, false);
- });
-
- it('test service - initNodeActive', () => {
- const selectedNode = treeService.rootNodes[ 0 ];
- selectedNode.isDisabled = true;
- treeService.initNodeActive(selectedNode, false);
- expect(treeService.getSelectedNodeList().length).toEqual(0);
- selectedNode.isDisabled = false;
- treeService.initNodeActive(selectedNode, false);
- expect(treeService.getSelectedNodeList().length).toEqual(1);
- expect(treeService.getSelectedNodeList()[ 0 ].title).toEqual('root1');
- });
-
- it('test service - dropAndApply', () => {
+ // can not dispatchTouchEvent with pos, test alone
+ it('test drag drop with dragPos', () => {
// init selected node
- treeService.selectedNode = treeService.rootNodes[ 0 ].getChildren()[ 0 ]; // child1
- // drop
- // dragPos = 2, not drop
- let targetNode = treeService.rootNodes[ 2 ]; // root3
- treeService.dropAndApply(targetNode, 2);
- // dragPos = -1, pre
+ treeService = treeInstance.treeComponent.nzTreeService;
+ const dragNode = treeElement.querySelectorAll('li')[ 1 ];
+ dispatchTouchEvent(dragNode, 'dragstart');
+ fixture.detectChanges();
+ // drop 0-0-0 to 0-0 pre
+ let targetNode = treeService.rootNodes[ 0 ]; // 0-0
treeService.dropAndApply(targetNode, -1);
- expect(treeService.rootNodes[ 2 ].level).toEqual(0);
- expect(treeService.rootNodes[ 2 ].title).toEqual('child1');
- // dragPos = -1, next
- treeService.selectedNode = treeService.rootNodes[ 2 ]; // child1
- targetNode = treeService.rootNodes[ 3 ];
+ expect(treeService.rootNodes[ 0 ].title).toEqual('0-0-0');
+ expect(treeService.rootNodes[ 0 ].level).toEqual(0);
+
+ // drop 0-0-0 to 0-0-1 next
+ treeService.selectedNode = treeService.rootNodes[ 0 ];
+ targetNode = treeService.rootNodes[ 1 ].getChildren()[ 0 ]; // 0-0-1
treeService.dropAndApply(targetNode, 1);
- expect(treeService.rootNodes[ 3 ].title).toEqual('child1');
- });
+ expect(treeService.rootNodes[ 0 ].getChildren()[ 1 ].title).toEqual('0-0-0');
+ expect(treeService.rootNodes[ 0 ].getChildren()[ 1 ].level).toEqual(1);
- it('test service - dropAndApply - has - parent', () => {
- // init selected node
- treeService.selectedNode = treeService.rootNodes[ 0 ].getChildren()[ 0 ]; // child1
- // drop to child2.2 pre
- const targetNode = treeService.rootNodes[ 1 ].getChildren()[ 1 ]; // child2.2
- treeService.dropAndApply(targetNode, -1);
- expect(treeService.rootNodes[ 1 ].getChildren()[ 1 ].title).toEqual('child1');
+ // drop 0-0-1 to 0-0-0 next
+ treeService.selectedNode = treeService.rootNodes[ 0 ].getChildren()[ 0 ];
+ targetNode = treeService.rootNodes[ 0 ].getChildren()[ 1 ]; // 0-0-1
+ treeService.dropAndApply(targetNode, 1);
+ expect(treeService.rootNodes[ 0 ].getChildren()[ 0 ].title).toEqual('0-0-0');
});
- });
- describe('strict mode', () => {
- treeInstance = null;
- fixture = null;
- let treeElement: HTMLElement;
- beforeEach(async(() => {
- TestBed.configureTestingModule({
- imports : [ NzTreeModule, NoopAnimationsModule, FormsModule, ReactiveFormsModule ],
- declarations: [ NzDemoStrictTreeComponent ]
- }).compileComponents();
- }));
+ it('test wrong drag event', fakeAsync(() => {
+ // drop node self
+ fixture.detectChanges();
+ const dragStartSpy = spyOn(treeInstance, 'onDragStart');
+ const dropSpy = spyOn(treeInstance, 'onDrop');
+ const dragEndSpy = spyOn(treeInstance, 'onDragEnd');
+ const dragNode = treeElement.querySelector('[title=\'0-1\']');
+ let dropNode = treeElement.querySelector('[title=\'0-2\']');
- beforeEach(fakeAsync(() => {
- fixture = TestBed.createComponent(NzDemoStrictTreeComponent);
- treeInstance = fixture.debugElement.componentInstance;
- treeElement = fixture.debugElement.query(By.directive(NzTreeComponent)).nativeElement;
+ // drop 0-1 to 0-2(leaf node)
+ dispatchTouchEvent(dragNode, 'dragstart');
+ dispatchTouchEvent(dropNode, 'dragover');
+ dispatchTouchEvent(dropNode, 'drop');
fixture.detectChanges();
- tick(1000);
+ dropNode = treeElement.querySelector('[title=\'0-2\']');
+ expect(dropSpy).toHaveBeenCalledTimes(0);
+ expect(dropNode.parentElement.querySelector('[title=\'0-1\']')).toBeNull();
+ // dragend
+ dispatchTouchEvent(dropNode, 'dragend');
fixture.detectChanges();
+ expect(dragEndSpy).toHaveBeenCalledTimes(1);
+ // drop to itself
+ dispatchTouchEvent(dragNode, 'dragstart');
+ dispatchTouchEvent(dragNode, 'dragover');
+ dispatchTouchEvent(dragNode, 'drop');
+ fixture.detectChanges();
+ expect(dropSpy).toHaveBeenCalledTimes(0);
+ // dragend
+ dispatchTouchEvent(dropNode, 'dragend');
+ fixture.detectChanges();
+ expect(dragEndSpy).toHaveBeenCalledTimes(2);
}));
- it('should create', () => {
- expect(treeInstance).toBeTruthy();
- });
-
- it('should check strictly', () => {
- fixture.detectChanges();
- // check child1
- let targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 0 ];
- dispatchMouseEvent(targetNode, 'click');
+ it('test drag event nzBeforeDrop', () => {
+ const dropSpy = spyOn(treeInstance, 'onDrop');
+ const dragNode = treeElement.querySelector('[title=\'0-2\']');
+ let dropNode = treeElement.querySelector('[title=\'0-1\']');
+ treeInstance.beforeDrop = (arg: NzFormatBeforeDropEvent): Observable => {
+ return of(true);
+ };
fixture.detectChanges();
- expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(2);
- // cancel
- targetNode = treeElement.querySelectorAll('.ant-tree-checkbox')[ 0 ];
- dispatchMouseEvent(targetNode, 'click');
+
+ dispatchTouchEvent(dragNode, 'dragstart');
+ dispatchTouchEvent(dropNode, 'dragover');
+ // drop 0-2 to 0-1
+ dispatchTouchEvent(dropNode, 'drop');
fixture.detectChanges();
- expect(treeElement.querySelectorAll('.ant-tree-checkbox-checked').length).toEqual(1);
+ dropNode = treeElement.querySelector('[title=\'0-1\']');
+ expect(dropNode.parentElement.querySelector('[title=\'0-2\']')).toBeDefined();
});
+
});
-});
-// -------------------------------------------
-// | Testing Components
-// -------------------------------------------
-@Component({
- selector: 'nz-demo-tree-strict',
- template: `
-
-
- `
-})
-class NzDemoStrictTreeComponent {
- checkedKeys = [ '100011' ];
- nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
- children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- checked : true,
- children: []
- },
- {
- title : 'child1.2',
- key : '100012',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf : true,
- disabled: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- },
- {
- title: 'child2',
- key : '10002'
- }
- ]
- })
- ];
-}
+});
@Component({
- selector: 'nz-demo-tree-basic',
+ selector: 'nz-test-tree-basic-controlled',
template: `
+ [nzExpandAll]="expandAll"
+ [nzAsyncData]="asyncData"
+ (nzSearchValueChange)="nzEvent($event)"
+ (nzClick)="nzEvent($event)"
+ (nzDblClick)="nzEvent($event)"
+ (nzContextMenu)="nzEvent($event)"
+ (nzExpandChange)="nzEvent($event)"
+ (nzCheckBoxChange)="nzEvent($event)">
`
})
-class NzDemoBasicTreeComponent {
- @ViewChild(NzTreeComponent) treeComponent: NzTreeComponent;
- expandKeys = [ '1001', '10001' ];
- checkedKeys = [ '10001' ];
- selectedKeys = [ '10001', '100011' ];
+
+export class NzTestTreeBasicControlledComponent {
+ @ViewChild('treeComponent') treeComponent: NzTreeComponent;
+ searchValue;
multiple = true;
- expandDefault = false;
- showLine = false;
- showExpand = true;
- searchValue = '';
- nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
+ expandAll = false;
+ asyncData = false;
+ checkStrictly = false;
+ defaultCheckedKeys = [ '0-0-0' ];
+ defaultSelectedKeys = [ '0-0-0-0' ];
+ defaultExpandedKeys = [ '0-0-0', '0-0-1' ];
+
+ nodes = [ {
+ title : '0-0',
+ key : '0-0',
+ expanded: true,
+ children: [ {
+ title : '0-0-0',
+ key : '0-0-0',
children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- children: []
- },
- {
- title : 'child1.2',
- key : '100012',
- disabled: true,
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf : true,
- disableCheckbox: true
- }
- ]
- }
- ]
- },
- {
- title: 'child2',
- key : '10002'
- }
+ { title: '0-0-0-0', key: '0-0-0-0', isLeaf: true },
+ { title: '0-0-0-1', key: '0-0-0-1', isLeaf: true },
+ { title: '0-0-0-2', key: '0-0-0-2', isLeaf: true }
]
- }),
- new NzTreeNode({
- title : 'root2',
- key : '1002',
+ }, {
+ title : '0-0-1',
+ key : '0-0-1',
children: [
- {
- title : 'child2.1',
- key : '10021',
- 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',
- key : '10022',
- children: [
- {
- title: 'grandchild2.2.1',
- key : '100221'
- }
- ]
- }
+ { title: '0-0-1-0', key: '0-0-1-0', isLeaf: true },
+ { title: '0-0-1-1', key: '0-0-1-1', isLeaf: true },
+ { title: '0-0-1-2', key: '0-0-1-2', isLeaf: true }
]
- }),
- new NzTreeNode({ title: 'root3', key: '1003' })
- ];
-
- onClick(): void {
- }
-
- onDblClick(): void {
- }
-
- onContextMenu(): void {
- }
-
- onCheck(): void {
- }
-
- onExpand(): void {
- }
-
- onSearch(): void {
+ }, {
+ title : '0-0-2',
+ key : '0-0-2',
+ isLeaf: true
+ } ]
+ }, {
+ title : '0-1',
+ key : '0-1',
+ children: [
+ { title: '0-1-0-0', key: '0-1-0-0', isLeaf: true },
+ { title: '0-1-0-1', key: '0-1-0-1', isLeaf: true },
+ { title: '0-1-0-2', key: '0-1-0-2', isLeaf: true }
+ ]
+ }, {
+ title : '0-2',
+ key : '0-2',
+ disabled: true,
+ isLeaf : true
+ } ];
+
+ nzEvent(event: NzFormatEmitEvent): void {
+ // console.log(event.eventName, event);
}
}
-// -------------------------------------------
-// | Testing Async Components
-// -------------------------------------------
-
-@Component({
- selector: 'nz-demo-tree-async',
- template: `
-
- `,
- styles : []
-})
-
-class NzDemoAsyncTreeComponent {
- @ViewChild(NzTreeComponent) treeComponent: NzTreeComponent;
- nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
- children: []
- }),
- new NzTreeNode({
- title : 'root2',
- key : '1002',
- children: []
- }),
- new NzTreeNode({
- title: 'root3',
- key : '1003'
- })
- ];
-
- onExpand(data: NzFormatEmitEvent): void {
- }
-}
-
// -------------------------------------------
// | Testing Draggable Components
// -------------------------------------------
@@ -726,107 +582,88 @@ class NzDemoAsyncTreeComponent {
selector: 'nz-demo-tree-draggable',
template: `
- `,
- styles : []
+ (nzOnDragStart)="onDragStart($event)"
+ (nzOnDragEnter)="onDragEnter($event)"
+ (nzOnDragLeave)="onDragLeave($event)"
+ (nzOnDragOver)="onDragOver($event)"
+ (nzOnDrop)="onDrop($event)"
+ (nzOnDragEnd)="onDragEnd($event)">
+
+ `
})
-class NzDemoDraggableTreeComponent {
+export class NzTestTreeDraggableComponent {
@ViewChild(NzTreeComponent) treeComponent: NzTreeComponent;
- nodes = [
- new NzTreeNode({
- title : 'root1',
- key : '1001',
+ nodes = [ {
+ title : '0-0',
+ key : '00',
+ expanded: true,
+ children: [ {
+ title : '0-0-0',
+ key : '000',
+ expanded: true,
children: [
- {
- title : 'child1',
- key : '10001',
- children: [
- {
- title : 'child1.1',
- key : '100011',
- children: []
- },
- {
- title : 'child1.2',
- key : '100012',
- children: [
- {
- title : 'grandchild1.2.1',
- key : '1000121',
- isLeaf : true,
- disabled: true
- },
- {
- title : 'grandchild1.2.2',
- key : '1000122',
- isLeaf: true
- }
- ]
- }
- ]
- },
- {
- title: 'child2',
- key : '10002'
- }
+ { title: '0-0-0-0', key: '0000', isLeaf: true },
+ { title: '0-0-0-1', key: '0001', isLeaf: true },
+ { title: '0-0-0-2', key: '0002', isLeaf: true }
]
- }),
- new NzTreeNode({
- title : 'root2',
- key : '1002',
+ }, {
+ title : '0-0-1',
+ key : '001',
children: [
- {
- title : 'child2.1',
- key : '10021',
- children : [],
- disableCheckbox: true
- },
- {
- title : 'child2.2',
- key : '10022',
- children: [
- {
- title: 'grandchild2.2.1',
- key : '100221'
- }
- ]
- }
+ { title: '0-0-1-0', key: '0010', isLeaf: true },
+ { title: '0-0-1-1', key: '0011', isLeaf: true },
+ { title: '0-0-1-2', key: '0012', isLeaf: true }
]
- }),
- new NzTreeNode({ title: 'root3', key: '1003', expanded: true })
- ];
-
+ }, {
+ title: '0-0-2',
+ key : '002'
+ } ]
+ }, {
+ title : '0-1',
+ key : '01',
+ children: [ {
+ title : '0-1-0',
+ key : '010',
+ children: [
+ { title: '0-1-0-0', key: '0100', isLeaf: true },
+ { title: '0-1-0-1', key: '0101', isLeaf: true },
+ { title: '0-1-0-2', key: '0102', isLeaf: true }
+ ]
+ }, {
+ title : '0-1-1',
+ key : '011',
+ children: [
+ { title: '0-1-1-0', key: '0110', isLeaf: true },
+ { title: '0-1-1-1', key: '0111', isLeaf: true },
+ { title: '0-1-1-2', key: '0112', isLeaf: true }
+ ]
+ } ]
+ }, {
+ title : '0-2',
+ key : '02',
+ isLeaf: true
+ } ];
beforeDrop;
- onDragStart(): void {
- }
-
- onDragEnter(): void {
+ onDragStart(event: NzFormatEmitEvent): void {
}
- onDragOver(): void {
+ onDragEnter(event: NzFormatEmitEvent): void {
}
- onDragLeave(): void {
+ onDragOver(event: NzFormatEmitEvent): void {
}
- onDrop(): void {
+ onDragLeave(event: NzFormatEmitEvent): void {
}
- onDragEnd(): void {
+ onDrop(event: NzFormatEmitEvent): void {
}
- constructor(public nzTreeService: NzTreeService) {
+ onDragEnd(event: NzFormatEmitEvent): void {
}
}
diff --git a/components/tree/public-api.ts b/components/tree/public-api.ts
index 7c2c06d5a2b..ab361136129 100644
--- a/components/tree/public-api.ts
+++ b/components/tree/public-api.ts
@@ -1,6 +1,7 @@
export * from './interface';
+export * from './nz-tree.module';
export * from './nz-tree.component';
export * from './nz-tree-node.component';
export * from './nz-tree-node';
export * from './nz-tree.service';
-export * from './nz-tree.module';
+export * from './nz-tree-util';