Skip to content

Commit 68cb4b2

Browse files
fix(module:tree-view): re-rendering fix (#8035)
[ node.ts ]: 'hasContextShapeChanged' func previously didn't allow customization of how to compare data objects, now it will use treeControl.trackBy func to do it in proper and optimized way
1 parent e94da4e commit 68cb4b2

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

components/tree-view/node.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ export class NzTreeNodeDefDirective<T> extends CdkTreeNodeDef<T> {
131131
export class NzTreeVirtualScrollNodeOutletDirective<T> implements OnChanges {
132132
private _viewRef: EmbeddedViewRef<NzSafeAny> | null = null;
133133
@Input() data!: NzTreeVirtualNodeData<T>;
134+
@Input() compareBy?: ((value: T) => T | string | number) | null;
134135

135136
constructor(private _viewContainerRef: ViewContainerRef) {}
136137

@@ -170,11 +171,22 @@ export class NzTreeVirtualScrollNodeOutletDirective<T> implements OnChanges {
170171
return true;
171172
}
172173
}
173-
return ctxChange.previousValue?.data !== ctxChange.currentValue?.data;
174+
return (
175+
this.innerCompareBy(ctxChange.previousValue?.data ?? null) !==
176+
this.innerCompareBy(ctxChange.currentValue?.data ?? null)
177+
);
174178
}
175179
return true;
176180
}
177181

182+
get innerCompareBy(): (value: T | null) => T | string | number | null {
183+
return value => {
184+
if (value === null) return value;
185+
if (this.compareBy) return this.compareBy(value as T);
186+
return value;
187+
};
188+
}
189+
178190
private updateExistingContext(ctx: NzSafeAny): void {
179191
for (const propName of Object.keys(ctx)) {
180192
this._viewRef!.context[propName] = (this.data.context as NzSafeAny)[propName];

components/tree-view/tree-virtual-scroll-view.ts

+13-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
*/
55

66
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
7-
import { CdkTree, CdkTreeNodeOutletContext } from '@angular/cdk/tree';
7+
import { CdkTree, CdkTreeNodeOutletContext, BaseTreeControl } from '@angular/cdk/tree';
88
import {
99
ChangeDetectionStrategy,
1010
Component,
@@ -16,6 +16,8 @@ import {
1616
ViewEncapsulation
1717
} from '@angular/core';
1818

19+
import { NzSafeAny } from 'ng-zorro-antd/core/types';
20+
1921
import { NzTreeVirtualNodeData } from './node';
2022
import { NzTreeNodeOutletDirective } from './outlet';
2123
import { NzTreeView } from './tree';
@@ -34,7 +36,7 @@ const DEFAULT_SIZE = 28;
3436
[maxBufferPx]="nzMaxBufferPx"
3537
>
3638
<ng-container *cdkVirtualFor="let item of nodes; let i = index; trackBy: innerTrackBy">
37-
<ng-template nzTreeVirtualScrollNodeOutlet [data]="item"></ng-template>
39+
<ng-template nzTreeVirtualScrollNodeOutlet [data]="item" [compareBy]="compareBy"></ng-template>
3840
</ng-container>
3941
</cdk-virtual-scroll-viewport>
4042
</div>
@@ -74,6 +76,15 @@ export class NzTreeVirtualScrollViewComponent<T> extends NzTreeView<T> implement
7476
}
7577
}
7678

79+
get compareBy(): ((value: T) => NzSafeAny) | null {
80+
const baseTreeControl = this.treeControl as BaseTreeControl<T, NzSafeAny>;
81+
if (baseTreeControl.trackBy) {
82+
return baseTreeControl.trackBy;
83+
}
84+
85+
return null;
86+
}
87+
7788
override renderNodeChanges(data: T[] | readonly T[]): void {
7889
this.nodes = new Array(...data).map((n, i) => this.createNode(n, i));
7990
this._dataSourceChanged.next();

0 commit comments

Comments
 (0)