Skip to content

Commit

Permalink
perf(abc:st): optimize the button text performance of rendered (#1203)
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk committed Mar 7, 2021
1 parent b741b4c commit b480649
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 37 deletions.
48 changes: 42 additions & 6 deletions packages/abc/st/st-data-source.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { DecimalPipe } from '@angular/common';
import { HttpParams } from '@angular/common/http';
import { Host, Injectable } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { DomSanitizer } from '@angular/platform-browser';
import { DatePipe, YNPipe, _HttpClient } from '@delon/theme';
import { CurrencyService } from '@delon/util/format';
import { deepCopy, deepGet } from '@delon/util/other';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { Observable, of } from 'rxjs';
import { map } from 'rxjs/operators';
import {
STColumn,
STColumnFilter,
STColumnFilterMenu,
STData,
Expand All @@ -27,7 +28,7 @@ import {
STStatisticalResults,
STStatisticalType,
} from './st.interfaces';
import { _STColumn } from './st.types';
import { _STColumn, _STColumnButton, _STDataValue } from './st.types';

export interface STDataSourceOptions {
pi: number;
Expand Down Expand Up @@ -183,7 +184,7 @@ export class STDataSource {
);
}

private get(item: STData, col: _STColumn, idx: number): { text: string; _text: SafeHtml; org?: any; color?: string } {
private get(item: STData, col: _STColumn, idx: number): _STDataValue {
try {
if (col.format) {
const formatRes = col.format(item, col, idx) || '';
Expand Down Expand Up @@ -232,11 +233,11 @@ export class STDataSource {
break;
}
if (text == null) text = '';
return { text, _text: this.dom.bypassSecurityTrustHtml(text), org: value, color };
return { text, _text: this.dom.bypassSecurityTrustHtml(text), org: value, color, buttons: [] };
} catch (ex) {
const text = `INVALID DATA`;
console.error(`Failed to get data`, item, col, ex);
return { text, _text: this.dom.bypassSecurityTrustHtml(text), org: text };
return { text, _text: this.dom.bypassSecurityTrustHtml(text), org: text, buttons: [] };
}
}

Expand Down Expand Up @@ -288,7 +289,13 @@ export class STDataSource {
optimizeData(options: { columns: _STColumn[]; result: STData[]; rowClassName?: STRowClassName }): STData[] {
const { result, columns, rowClassName } = options;
for (let i = 0, len = result.length; i < len; i++) {
result[i]._values = columns.map(c => this.get(result[i], c, i));
result[i]._values = columns.map(c => {
if (Array.isArray(c.buttons) && c.buttons.length > 0) {
return { buttons: this.genButtons(c.buttons, result[i], c) };
}

return this.get(result[i], c, i);
});
if (rowClassName) {
result[i]._rowClassName = rowClassName(result[i], i);
}
Expand All @@ -300,6 +307,35 @@ export class STDataSource {
return typeof col.noIndex === 'function' ? col.noIndex(item, col, idx) : col.noIndex! + idx;
}

private genButtons(_btns: _STColumnButton[], item: STData, col: STColumn): _STColumnButton[] {
const fn = (btns: _STColumnButton[]): _STColumnButton[] => {
return btns.filter(btn => {
const result = btn.iif!(item, btn, col);
const isRenderDisabled = btn.iifBehavior === 'disabled';
btn._result = result;
btn._disabled = !result && isRenderDisabled;
if (btn.children!.length > 0) {
btn.children = fn(btn.children!);
}
return result || isRenderDisabled;
});
};

const res = fn(_btns);

const fnText = (btns: _STColumnButton[]): _STColumnButton[] => {
for (const btn of btns) {
btn._text = typeof btn.text === 'function' ? btn.text(item, btn) : btn.text || '';
if (btn.children!.length > 0) {
btn.children = fnText(btn.children!);
}
}
return btns;
};

return fnText(res);
}

// #region sort

private getValidSort(columns: _STColumn[]): STSortMap[] {
Expand Down
8 changes: 4 additions & 4 deletions packages/abc/st/st.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
></i>
<i *ngIf="btn.icon.iconfont" nz-icon [nzIconfont]="btn.icon.iconfont"></i>
</ng-container>
<span [innerHTML]="_btnText(i, btn)" [ngClass]="{ 'pl-xs': btn.icon }"></span>
<span [innerHTML]="btn._text" [ngClass]="{ 'pl-xs': btn.icon }"></span>
</ng-template>
<ng-template #titleTpl let-i>
<span [innerHTML]="i._text"></span>
Expand Down Expand Up @@ -248,14 +248,14 @@
<ng-template *ngSwitchCase="'widget'" st-widget-host [record]="i" [column]="c"></ng-template>
<span *ngSwitchDefault [innerHTML]="i._values[cIdx]._text" [attr.title]="c._isTruncate ? i._values[cIdx].text : null"></span>
</ng-container>
<ng-container *ngFor="let btn of _validBtns(c.buttons!, i, c); let last = last">
<ng-container *ngFor="let btn of i._values[cIdx].buttons; let last = last">
<a *ngIf="btn.children!.length > 0" nz-dropdown [nzDropdownMenu]="btnMenu" nzOverlayClassName="st__btn-sub">
<span [innerHTML]="_btnText(i, btn)"></span>
<span [innerHTML]="btn._text"></span>
<i nz-icon nzType="down"></i>
</a>
<nz-dropdown-menu #btnMenu="nzDropdownMenu">
<ul nz-menu>
<ng-container *ngFor="let subBtn of _validBtns(btn.children!, i, c)">
<ng-container *ngFor="let subBtn of btn.children!">
<li *ngIf="subBtn.type !== 'divider'" nz-menu-item [class.st__btn-disabled]="subBtn._disabled">
<ng-template [ngTemplateOutlet]="btnTpl" [ngTemplateOutletContext]="{ $implicit: i, btn: subBtn }"> </ng-template>
</li>
Expand Down
42 changes: 16 additions & 26 deletions packages/abc/st/st.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ import {
STStatisticalResults,
STWidthMode,
} from './st.interfaces';
import { _STColumn, _STHeader } from './st.types';
import { _STColumn, _STDataValue, _STHeader } from './st.types';

@Component({
selector: 'st',
Expand Down Expand Up @@ -104,7 +104,7 @@ export class STComponent implements AfterViewInit, OnChanges, OnDestroy {
static ngAcceptInputType_virtualMaxBufferPx: NumberInput;
static ngAcceptInputType_virtualMinBufferPx: NumberInput;

private unsubscribe$ = new Subject<void>();
private destroy$ = new Subject<void>();
private data$: Subscription;
private totalTpl = ``;
private cog: AlainSTConfig;
Expand Down Expand Up @@ -257,7 +257,7 @@ export class STComponent implements AfterViewInit, OnChanges, OnDestroy {
) {
this.setCog(configSrv.merge('st', ST_DEFAULT_CONFIG)!);

this.delonI18n.change.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
this.delonI18n.change.pipe(takeUntil(this.destroy$)).subscribe(() => {
this.locale = this.delonI18n.getData('st');
if (this._columns.length > 0) {
this.updateTotalTpl();
Expand All @@ -267,7 +267,7 @@ export class STComponent implements AfterViewInit, OnChanges, OnDestroy {

i18nSrv.change
.pipe(
takeUntil(this.unsubscribe$),
takeUntil(this.destroy$),
filter(() => this._columns.length > 0),
)
.subscribe(() => this.refreshColumns());
Expand Down Expand Up @@ -362,7 +362,7 @@ export class STComponent implements AfterViewInit, OnChanges, OnDestroy {
paginator: true,
...options,
})
.pipe(takeUntil(this.unsubscribe$))
.pipe(takeUntil(this.destroy$))
.subscribe(
result => resolvePromise(result),
error => {
Expand Down Expand Up @@ -390,7 +390,7 @@ export class STComponent implements AfterViewInit, OnChanges, OnDestroy {
if (typeof result.pageShow !== 'undefined') {
this._isPagination = result.pageShow;
}
this._data = result.list as STData[];
this._data = result.list;
this._statistical = result.statistical as STStatisticalResults;
this.changeEmit('loaded', result.list);
// Should be re-render in next tike when using virtual scroll
Expand All @@ -401,7 +401,7 @@ export class STComponent implements AfterViewInit, OnChanges, OnDestroy {
return this._refCheck();
} catch (error) {
this.setLoading(false);
if (!this.unsubscribe$.isStopped) {
if (!this.destroy$.isStopped) {
this.cdr.detectChanges();
this.error.emit({ type: 'req', error });
}
Expand Down Expand Up @@ -556,7 +556,12 @@ export class STComponent implements AfterViewInit, OnChanges, OnDestroy {
// recalculate no
this._columns
.filter(w => w.type === 'no')
.forEach(c => this._data.forEach((i, idx) => (i._values[c.__point!] = { _text: this.dataSource.getNoIndex(i, c, idx), org: idx })));
.forEach(c =>
this._data.forEach((i, idx) => {
const text = `${this.dataSource.getNoIndex(i, c, idx)}`;
i._values![c.__point!] = { text, _text: text, org: idx } as _STDataValue;
}),
);

return this.cd();
}
Expand Down Expand Up @@ -767,20 +772,6 @@ export class STComponent implements AfterViewInit, OnChanges, OnDestroy {
}
}

_btnText(record: STData, btn: STColumnButton): string {
return typeof btn.text === 'function' ? btn.text(record, btn) : btn.text || '';
}

_validBtns(btns: STColumnButton[], item: STData, col: STColumn): STColumnButton[] {
return btns.filter(btn => {
const result = btn.iif!(item, btn, col);
const isRenderDisabled = btn.iifBehavior === 'disabled';
btn._result = result;
btn._disabled = !result && isRenderDisabled;
return result || isRenderDisabled;
});
}

// #endregion

// #region export
Expand Down Expand Up @@ -835,7 +826,7 @@ export class STComponent implements AfterViewInit, OnChanges, OnDestroy {
});
(isObservable(obs$) ? obs$ : of(obs$))
.pipe(
takeUntil(this.unsubscribe$),
takeUntil(this.destroy$),
filter(res => res.length > 0),
)
.subscribe(res => {
Expand Down Expand Up @@ -931,8 +922,7 @@ export class STComponent implements AfterViewInit, OnChanges, OnDestroy {
}

ngOnDestroy(): void {
const { unsubscribe$ } = this;
unsubscribe$.next();
unsubscribe$.complete();
this.destroy$.next();
this.destroy$.complete();
}
}
16 changes: 15 additions & 1 deletion packages/abc/st/st.types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// tslint:disable: class-name
import { TemplateRef } from '@angular/core';
import { STColumn, STSortMap } from './st.interfaces';
import { SafeHtml } from '@angular/platform-browser';
import { STColumn, STColumnButton, STData, STSortMap } from './st.interfaces';

export interface _STColumn extends STColumn {
children?: _STColumn[];
Expand Down Expand Up @@ -32,3 +33,16 @@ export interface _STHeader {
rowSpan: number;
column: _STColumn;
}

export interface _STColumnButton<T extends STData = any> extends STColumnButton<T> {
_text?: string;
children?: _STColumnButton<T>[];
}

export interface _STDataValue {
text: string;
_text: SafeHtml;
org?: any;
color?: string;
buttons?: _STColumnButton[];
}
20 changes: 20 additions & 0 deletions packages/abc/st/test/st-data-source.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -831,6 +831,26 @@ describe('abc: table: data-souce', () => {
done();
});
});
it('should be buttons', done => {
options.data = [{ id: 1 }];
options.columns = [
{ title: '', index: 'id' },
{
title: 'btn',
iif: () => true,
buttons: [
{ text: 'btn1', iif: () => true, children: [] },
{ text: 'btn2', iif: () => true, children: [{ text: 'btn2-1', iif: () => true, children: [] }] },
],
},
] as _STColumn[];
srv.process(options).subscribe(res => {
const btns = res.list[0]._values[1].buttons;
expect(Array.isArray(btns)).toBe(true);
expect(btns.length).toBe(2);
done();
});
});
});

describe('[statistical]', () => {
Expand Down

0 comments on commit b480649

Please sign in to comment.