Skip to content

Commit 324ab5b

Browse files
authored
fix(module:cascader): invalid value and label when binding dynamically (#9338)
1 parent ddefc7f commit 324ab5b

2 files changed

Lines changed: 57 additions & 30 deletions

File tree

components/cascader/cascader.component.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ export class NzCascaderComponent
319319
@ViewChild(CdkConnectedOverlay, { static: false }) overlay!: CdkConnectedOverlay;
320320
@ViewChildren(NzCascaderOptionComponent) cascaderItems!: QueryList<NzCascaderOptionComponent>;
321321

322+
@Input() nzOptions: NzCascaderOption[] | null = [];
322323
@Input() nzOptionRender: TemplateRef<{ $implicit: NzCascaderOption; index: number }> | null = null;
323324
@Input({ transform: booleanAttribute }) nzShowInput = true;
324325
@Input({ transform: booleanAttribute }) nzShowArrow = true;
@@ -364,23 +365,6 @@ export class NzCascaderComponent
364365
@Input() nzSuffixIcon: string | TemplateRef<void> = 'down';
365366
@Input() nzExpandIcon: string | TemplateRef<void> = '';
366367

367-
@Input()
368-
get nzOptions(): NzCascaderOption[] | null {
369-
return this.cascaderService.nzOptions;
370-
}
371-
372-
set nzOptions(options: NzCascaderOption[] | null) {
373-
const nodes = this.coerceTreeNodes(options || []);
374-
this.treeService.initTree(nodes);
375-
this.cascaderService.columns = [nodes];
376-
this.updateSelectedNodes(true);
377-
378-
if (this.inSearchingMode) {
379-
this.cascaderService.setSearchingMode(this.inSearchingMode);
380-
this.cascaderService.prepareSearchOptions(this.inputValue);
381-
}
382-
}
383-
384368
get treeService(): NzCascaderTreeService {
385369
return this.nzTreeService as NzCascaderTreeService;
386370
}
@@ -569,7 +553,10 @@ export class NzCascaderComponent
569553
}
570554

571555
ngOnChanges(changes: SimpleChanges): void {
572-
const { nzStatus, nzSize, nzPlacement } = changes;
556+
const { nzStatus, nzSize, nzPlacement, nzOptions } = changes;
557+
if (nzOptions) {
558+
this.updateOptions();
559+
}
573560
if (nzStatus) {
574561
this.setStatusStyles(this.nzStatus, this.hasFeedback);
575562
}
@@ -966,6 +953,18 @@ export class NzCascaderComponent
966953
this.dropdownPosition = placement as NzSelectPlacementType;
967954
}
968955

956+
private updateOptions(): void {
957+
const nodes = this.coerceTreeNodes(this.nzOptions || []);
958+
this.treeService.initTree(nodes);
959+
this.cascaderService.setColumnData(nodes, 0);
960+
this.updateSelectedNodes(true);
961+
962+
if (this.inSearchingMode) {
963+
this.cascaderService.setSearchingMode(this.inSearchingMode);
964+
this.cascaderService.prepareSearchOptions(this.inputValue);
965+
}
966+
}
967+
969968
private isActionTrigger(action: 'click' | 'hover'): boolean {
970969
return typeof this.nzTriggerAction === 'string'
971970
? this.nzTriggerAction === action

components/cascader/cascader.spec.ts

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,7 +1494,7 @@ describe('cascader', () => {
14941494
fixture.detectChanges();
14951495
const itemEl1 = getItemAtColumnAndRow(1, 1)!;
14961496
expect(testComponent.cascader.inSearchingMode).toBe(true);
1497-
expect(itemEl1.innerText).toBe('Zhejiang / Hangzhou / West Lake');
1497+
expect(itemEl1.innerText).toBe('Zhejiang New / Hangzhou New / West Lake New');
14981498

14991499
itemEl1.click();
15001500
fixture.detectChanges();
@@ -1506,6 +1506,29 @@ describe('cascader', () => {
15061506
expect(testComponent.values!.join(',')).toBe('zhejiang,hangzhou,xihu');
15071507
}));
15081508

1509+
it('should support nzValueProperty', fakeAsync(() => {
1510+
testComponent.nzShowSearch = true;
1511+
testComponent.nzValueProperty = 'v';
1512+
fixture.detectChanges();
1513+
cascader.nativeElement.click();
1514+
fixture.detectChanges();
1515+
testComponent.cascader.inputValue = 'o';
1516+
testComponent.cascader.setMenuVisible(true);
1517+
fixture.detectChanges();
1518+
const itemEl1 = getItemAtColumnAndRow(1, 1)!;
1519+
expect(testComponent.cascader.inSearchingMode).toBe(true);
1520+
expect(itemEl1.innerText).toBe('Zhejiang / Hangzhou / West Lake');
1521+
1522+
itemEl1.click();
1523+
fixture.detectChanges();
1524+
flush();
1525+
fixture.detectChanges();
1526+
expect(testComponent.cascader.inSearchingMode).toBe(false);
1527+
expect(testComponent.cascader.menuVisible).toBe(false);
1528+
expect(testComponent.cascader.inputValue).toBe('');
1529+
expect(testComponent.values!.join(',')).toBe('zhejiang-new,hangzhou-new,xihu-new');
1530+
}));
1531+
15091532
it('should support custom filter', fakeAsync(() => {
15101533
testComponent.nzShowSearch = {
15111534
filter(inputValue: string, path: NzCascaderOption[]): boolean {
@@ -2215,43 +2238,50 @@ const options1: NzCascaderOption[] = [
22152238
{
22162239
value: 'zhejiang',
22172240
label: 'Zhejiang',
2218-
l: 'Zhejiang',
2241+
v: 'zhejiang-new',
2242+
l: 'Zhejiang New',
22192243
children: [
22202244
{
22212245
value: 'hangzhou',
22222246
label: 'Hangzhou',
2223-
l: 'Hangzhou',
2247+
v: 'hangzhou-new',
2248+
l: 'Hangzhou New',
22242249
children: [
22252250
{
22262251
value: 'xihu',
2227-
l: 'West Lake',
22282252
label: 'West Lake',
2253+
v: 'xihu-new',
2254+
l: 'West Lake New',
22292255
isLeaf: true
22302256
}
22312257
]
22322258
},
22332259
{
22342260
value: 'ningbo',
22352261
label: 'Ningbo',
2236-
l: 'Ningbo',
2262+
v: 'ningbo-new',
2263+
l: 'Ningbo New',
22372264
isLeaf: true
22382265
}
22392266
]
22402267
},
22412268
{
22422269
value: 'jiangsu',
22432270
label: 'Jiangsu',
2244-
l: 'Jiangsu',
2271+
v: 'jiangsu-new',
2272+
l: 'Jiangsu New',
22452273
children: [
22462274
{
22472275
value: 'nanjing',
22482276
label: 'Nanjing',
2249-
l: 'Nanjing',
2277+
v: 'nanjing-new',
2278+
l: 'Nanjing New',
22502279
children: [
22512280
{
22522281
value: 'zhonghuamen',
22532282
label: 'Zhong Hua Men',
2254-
l: 'Zhong Hua Men',
2283+
v: 'zhonghuamen-new',
2284+
l: 'Zhong Hua Men New',
22552285
isLeaf: true
22562286
}
22572287
]
@@ -2407,6 +2437,7 @@ const options5: NzSafeAny[] = [];
24072437
template: `
24082438
<nz-cascader
24092439
[(ngModel)]="values"
2440+
[nzOptions]="nzOptions"
24102441
[nzAllowClear]="nzAllowClear"
24112442
[nzAutoFocus]="nzAutoFocus"
24122443
[nzChangeOn]="nzChangeOn"
@@ -2416,20 +2447,19 @@ const options5: NzSafeAny[] = [];
24162447
[nzExpandIcon]="nzExpandIcon"
24172448
[nzExpandTrigger]="nzExpandTrigger"
24182449
[nzLabelProperty]="nzLabelProperty"
2450+
[nzValueProperty]="nzValueProperty"
24192451
[nzLabelRender]="nzLabelRender"
24202452
[nzMenuClassName]="nzMenuClassName"
24212453
[nzMenuStyle]="nzMenuStyle"
24222454
[nzMouseEnterDelay]="nzMouseEnterDelay"
24232455
[nzMouseLeaveDelay]="nzMouseLeaveDelay"
2424-
[nzOptions]="nzOptions"
24252456
[nzPlaceHolder]="nzPlaceHolder"
24262457
[nzShowArrow]="nzShowArrow"
24272458
[nzShowInput]="nzShowInput"
24282459
[nzShowSearch]="nzShowSearch"
24292460
[nzSize]="nzSize"
24302461
[nzTriggerAction]="nzTriggerAction"
24312462
[nzSuffixIcon]="nzSuffixIcon"
2432-
[nzValueProperty]="nzValueProperty"
24332463
[nzBackdrop]="nzBackdrop"
24342464
[nzPlacement]="nzPlacement"
24352465
[nzVariant]="nzVariant"
@@ -2488,7 +2518,6 @@ export class NzDemoCascaderDefaultComponent {
24882518
imports: [FormsModule, NzCascaderModule],
24892519
template: `
24902520
<nz-cascader
2491-
[nzOptions]="nzOptions"
24922521
[(ngModel)]="values"
24932522
[nzLoadData]="nzLoadData"
24942523
(ngModelChange)="onValueChanges($event)"
@@ -2499,7 +2528,6 @@ export class NzDemoCascaderDefaultComponent {
24992528
export class NzDemoCascaderLoadDataComponent {
25002529
@ViewChild(NzCascaderComponent, { static: true }) cascader!: NzCascaderComponent;
25012530

2502-
nzOptions: NzSafeAny[] | null = null;
25032531
values: string[] | null = null;
25042532

25052533
nzLoadData = (node: NzSafeAny, index: number): PromiseLike<NzSafeAny> => {

0 commit comments

Comments
 (0)