Skip to content

Commit

Permalink
fix(module:tree-view): re-rendering fix (#8035)
Browse files Browse the repository at this point in the history
[ 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
  • Loading branch information
oleksandr-codefresh committed Sep 12, 2023
1 parent e94da4e commit 68cb4b2
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
14 changes: 13 additions & 1 deletion components/tree-view/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ export class NzTreeNodeDefDirective<T> extends CdkTreeNodeDef<T> {
export class NzTreeVirtualScrollNodeOutletDirective<T> implements OnChanges {
private _viewRef: EmbeddedViewRef<NzSafeAny> | null = null;
@Input() data!: NzTreeVirtualNodeData<T>;
@Input() compareBy?: ((value: T) => T | string | number) | null;

constructor(private _viewContainerRef: ViewContainerRef) {}

Expand Down Expand Up @@ -170,11 +171,22 @@ export class NzTreeVirtualScrollNodeOutletDirective<T> implements OnChanges {
return true;
}
}
return ctxChange.previousValue?.data !== ctxChange.currentValue?.data;
return (
this.innerCompareBy(ctxChange.previousValue?.data ?? null) !==
this.innerCompareBy(ctxChange.currentValue?.data ?? null)
);
}
return true;
}

get innerCompareBy(): (value: T | null) => T | string | number | null {
return value => {
if (value === null) return value;
if (this.compareBy) return this.compareBy(value as T);
return value;
};
}

private updateExistingContext(ctx: NzSafeAny): void {
for (const propName of Object.keys(ctx)) {
this._viewRef!.context[propName] = (this.data.context as NzSafeAny)[propName];
Expand Down
15 changes: 13 additions & 2 deletions components/tree-view/tree-virtual-scroll-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { CdkTree, CdkTreeNodeOutletContext } from '@angular/cdk/tree';
import { CdkTree, CdkTreeNodeOutletContext, BaseTreeControl } from '@angular/cdk/tree';
import {
ChangeDetectionStrategy,
Component,
Expand All @@ -16,6 +16,8 @@ import {
ViewEncapsulation
} from '@angular/core';

import { NzSafeAny } from 'ng-zorro-antd/core/types';

import { NzTreeVirtualNodeData } from './node';
import { NzTreeNodeOutletDirective } from './outlet';
import { NzTreeView } from './tree';
Expand All @@ -34,7 +36,7 @@ const DEFAULT_SIZE = 28;
[maxBufferPx]="nzMaxBufferPx"
>
<ng-container *cdkVirtualFor="let item of nodes; let i = index; trackBy: innerTrackBy">
<ng-template nzTreeVirtualScrollNodeOutlet [data]="item"></ng-template>
<ng-template nzTreeVirtualScrollNodeOutlet [data]="item" [compareBy]="compareBy"></ng-template>
</ng-container>
</cdk-virtual-scroll-viewport>
</div>
Expand Down Expand Up @@ -74,6 +76,15 @@ export class NzTreeVirtualScrollViewComponent<T> extends NzTreeView<T> implement
}
}

get compareBy(): ((value: T) => NzSafeAny) | null {
const baseTreeControl = this.treeControl as BaseTreeControl<T, NzSafeAny>;
if (baseTreeControl.trackBy) {
return baseTreeControl.trackBy;
}

return null;
}

override renderNodeChanges(data: T[] | readonly T[]): void {
this.nodes = new Array(...data).map((n, i) => this.createNode(n, i));
this._dataSourceChanged.next();
Expand Down

0 comments on commit 68cb4b2

Please sign in to comment.