Skip to content

Commit

Permalink
fix(module:cascader): fix dynamic loading error (#1931)
Browse files Browse the repository at this point in the history
* fix(module:cascader): fix dynamic loading error

close #1927

* fix test
  • Loading branch information
wendzhue authored and hsuanxyz committed Aug 19, 2018
1 parent 5ded2c6 commit d4d24fb
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 21 deletions.
2 changes: 1 addition & 1 deletion components/cascader/doc/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Cascade selection box.
| `[nzPlaceHolder]` | input placeholder | string | 'Please select' |
| `[nzShowArrow]` | Whether show arrow | boolean | true |
| `[nzShowInput]` | Whether show input | boolean | true |
| `[nzShowSearch]` | Whether support search | `boolean` `NzShowSearchOptions` | `false` |
| `[nzShowSearch]` | Whether support search. Cannot be used with `[nzLoadData]` at the same time | `boolean` `NzShowSearchOptions` | `false` |
| `[nzSize]` | input size, one of `large` `default` `small` | string | `default` |
| `[nzValueProperty]` | the value property name of options | string | 'value' |
| `(ngModelChange)` | Emit on values change | `EventEmitter<any[]>` | - |
Expand Down
2 changes: 1 addition & 1 deletion components/cascader/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ subtitle: 级联选择
| `[nzPlaceHolder]` | 输入框占位文本 | string | '请选择' |
| `[nzShowArrow]` | 是否显示箭头 | boolean | true |
| `[nzShowInput]` | 显示输入框 | boolean | true |
| `[nzShowSearch]` | 是否支持搜索,默认情况下对 `label` 进行全匹配搜索 | `boolean` `NzShowSearchOptions` | `false` |
| `[nzShowSearch]` | 是否支持搜索,默认情况下对 `label` 进行全匹配搜索,不能和 `[nzLoadData]` 同时使用 | `boolean` `NzShowSearchOptions` | `false` |
| `[nzSize]` | 输入框大小,可选 `large` `default` `small` | string | `default` |
| `[nzValueProperty]` | 选项的实际值的属性名 | string | 'value' |
| `(ngModelChange)` | 值发生变化时触发 | `EventEmitter<any[]>` | - |
Expand Down
61 changes: 42 additions & 19 deletions components/cascader/nz-cascader.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,20 +166,25 @@ export class NzCascaderComponent implements OnInit, OnDestroy, ControlValueAcces

set inputValue(inputValue: string) {
this._inputValue = inputValue;
const willBeInSearch = !!inputValue;

if (!this.inSearch) {
// 搜索状态变动之前,如要进入则要保留之前激活选项的快照,退出搜索状态要还原该快照
if (!this.inSearch && willBeInSearch) {
this.oldActivatedOptions = this.activatedOptions;
this.activatedOptions = [];
} else {
this.searchWidthStyle = `${this.input.nativeElement.offsetWidth}px`;
} else if (this.inSearch && !willBeInSearch) {
this.activatedOptions = this.oldActivatedOptions;
}

this.inSearch = !!inputValue;
// 搜索状态变更之后
this.inSearch = !!willBeInSearch;
if (this.inSearch) {
this.searchWidthStyle = `${this.input.nativeElement.offsetWidth}px`;
this.prepareSearchValue();
} else {
this.nzColumns = this.oldColumnsHolder;
if (this.showSearch) {
this.nzColumns = this.oldColumnsHolder;
}
this.searchWidthStyle = '';
}
this.setClassMap();
Expand Down Expand Up @@ -258,6 +263,7 @@ export class NzCascaderComponent implements OnInit, OnDestroy, ControlValueAcces
set nzShowSearch(value: boolean | NzShowSearchOptions) {
this.showSearch = value;
}

get nzShowSearch(): boolean | NzShowSearchOptions {
return this.showSearch;
}
Expand Down Expand Up @@ -460,8 +466,8 @@ export class NzCascaderComponent implements OnInit, OnDestroy, ControlValueAcces
private setLabelClass(): void {
this._labelCls = {
[ `${this.prefixCls}-picker-label` ]: true,
[ `${this.prefixCls}-show-search`]: !!this.nzShowSearch,
[ `${this.prefixCls}-focused`]: !!this.nzShowSearch && this.isFocused && !this._inputValue
[ `${this.prefixCls}-show-search` ] : !!this.nzShowSearch,
[ `${this.prefixCls}-focused` ] : !!this.nzShowSearch && this.isFocused && !this._inputValue
};
}

Expand Down Expand Up @@ -686,7 +692,9 @@ export class NzCascaderComponent implements OnInit, OnDestroy, ControlValueAcces
return;
}
this.onTouched(); // set your control to 'touched'
if (this.nzShowSearch) { this.focus(); }
if (this.nzShowSearch) {
this.focus();
}

if (this.isClickTiggerAction()) {
this.delaySetMenuVisible(!this.menuVisible, 100);
Expand Down Expand Up @@ -941,7 +949,9 @@ export class NzCascaderComponent implements OnInit, OnDestroy, ControlValueAcces
* @param event 鼠标事件
*/
onOptionClick(option: CascaderOption, index: number, event: Event): void {
if (event) { event.preventDefault(); }
if (event) {
event.preventDefault();
}

// Keep focused state for keyboard support
this.el.focus();
Expand Down Expand Up @@ -1193,7 +1203,9 @@ export class NzCascaderComponent implements OnInit, OnDestroy, ControlValueAcces
const defaultFilter = (inputValue: string, p: CascaderOption[]): boolean => {
let flag = false;
p.forEach(n => {
if (n.label.indexOf(inputValue) > -1) { flag = true; }
if (n.label.indexOf(inputValue) > -1) {
flag = true;
}
});
return flag;
};
Expand All @@ -1207,9 +1219,16 @@ export class NzCascaderComponent implements OnInit, OnDestroy, ControlValueAcces
const disabled = forceDisabled || node.disabled;
path.push(node);
node.children.forEach((sNode) => {
if (!sNode.parent) { sNode.parent = node; } /** 搜索的同时建立 parent 连接,因为用户直接搜索的话是没有建立连接的,会提升从叶子节点回溯的难度 */
if (!sNode.isLeaf) { loopParent(sNode, disabled); }
if (sNode.isLeaf || !sNode.children) { loopChild(sNode, disabled); }
if (!sNode.parent) {
sNode.parent = node;
}
/** 搜索的同时建立 parent 连接,因为用户直接搜索的话是没有建立连接的,会提升从叶子节点回溯的难度 */
if (!sNode.isLeaf) {
loopParent(sNode, disabled);
}
if (sNode.isLeaf || !sNode.children) {
loopChild(sNode, disabled);
}
});
path.pop();
};
Expand All @@ -1221,15 +1240,17 @@ export class NzCascaderComponent implements OnInit, OnDestroy, ControlValueAcces
results.push({
disabled,
isLeaf: true,
path: cPath,
label: cPath.map(p => p.label).join(' / ')
path : cPath,
label : cPath.map(p => p.label).join(' / ')
} as CascaderSearchOption);
}
path.pop();
};

this.oldColumnsHolder[0].forEach(node => loopParent(node));
if (sorter) { results.sort((a, b) => sorter(a.path, b.path, this._inputValue)); }
this.oldColumnsHolder[ 0 ].forEach(node => loopParent(node));
if (sorter) {
results.sort((a, b) => sorter(a.path, b.path, this._inputValue));
}
this.nzColumns = [ results ];
}

Expand All @@ -1245,9 +1266,11 @@ export class NzCascaderComponent implements OnInit, OnDestroy, ControlValueAcces
setTimeout(() => {
this.inputValue = ''; // Not only remove `inputValue` but also reverse `nzColumns` in the hook.
const index = result.path.length - 1;
const destiNode = result.path[index];
const destiNode = result.path[ index ];
const mockClickParent = (node: CascaderOption, cIndex: number) => {
if (node && node.parent) { mockClickParent(node.parent, cIndex - 1); }
if (node && node.parent) {
mockClickParent(node.parent, cIndex - 1);
}
this.onOptionClick(node, cIndex, event);
};
mockClickParent(destiNode, index);
Expand Down
42 changes: 42 additions & 0 deletions components/cascader/nz-cascader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1311,6 +1311,13 @@ describe('cascader', () => {
it('should support search', (done) => {
fixture.detectChanges();
testComponent.nzShowSearch = true;
fixture.detectChanges();
// const input: HTMLElement = cascader.nativeElement.querySelector('.ant-cascader-input');
const spy = spyOn(testComponent.cascader, 'focus');
cascader.nativeElement.click();
fixture.detectChanges();
// expect(document.activeElement).toBe(input);
expect(spy).toHaveBeenCalled();
testComponent.cascader.inputValue = 'o';
testComponent.cascader.setMenuVisible(true);
fixture.detectChanges();
Expand Down Expand Up @@ -1548,6 +1555,41 @@ describe('cascader', () => {
expect(testComponent.values.join(',')).toBe('zhejiang,hangzhou,xihu');
}));

it('should not emit error after clear search and reopen it', fakeAsync(() => {
fixture.detectChanges();
testComponent.cascader.setMenuVisible(true);
fixture.detectChanges();
tick(1000); // wait for first row to load finish
fixture.detectChanges();
const itemEl1 = overlayContainerElement.querySelector('.ant-cascader-menu:nth-child(1) .ant-cascader-menu-item:nth-child(1)') as HTMLElement; // 第1列第1个
itemEl1.click();
fixture.detectChanges();
tick(600);
fixture.detectChanges();
const itemEl2 = overlayContainerElement.querySelector('.ant-cascader-menu:nth-child(2) .ant-cascader-menu-item:nth-child(1)') as HTMLElement; // 第2列第1个
itemEl2.click();
fixture.detectChanges();
tick(600);
fixture.detectChanges();
const itemEl3 = overlayContainerElement.querySelector('.ant-cascader-menu:nth-child(3) .ant-cascader-menu-item:nth-child(1)') as HTMLElement; // 第3列第1个
itemEl3.click();
fixture.detectChanges();
tick(600);
fixture.detectChanges();
flush(); // wait for cdk-overlay to close
fixture.detectChanges();
itemEl3.click(); // re-click again, this time it is a leaf
fixture.detectChanges();
tick(600);
fixture.detectChanges();
flush(); // wait for cdk-overlay to close
fixture.detectChanges();
cascader.nativeElement.querySelector('.ant-cascader-picker-clear').click();
testComponent.cascader.setMenuVisible(true);
fixture.detectChanges();
expect(testComponent.values.length).toBe(0);
}));

});
});

Expand Down

0 comments on commit d4d24fb

Please sign in to comment.