bixi
Version:
企业级中后台前端解决方案
191 lines (172 loc) • 6.02 kB
text/typescript
import {
ChangeDetectorRef,
Component,
EventEmitter,
Input,
OnChanges,
OnDestroy,
OnInit,
Output,
SimpleChanges,
ViewEncapsulation
} from '@angular/core';
import { BixiI18nService } from '@bixi/core/i18n';
import { isNull } from '@bixi/core/utils';
import { NzSafeAny } from 'ng-zorro-antd/core/types';
import { Subscription } from 'rxjs';
import { filter } from 'rxjs/operators';
import { ColTemplateService } from './cols/col-template.service';
import { BixiPaginationListBase, IPagination, PAGE_SIZE_OPTIONS } from './pagination-list.base';
import { BixiTableUtilsService } from './table-utils.service';
import { BixiTableService } from './table.service';
import { EColType, ICheckboxCol, ICols, IFilterParams, IInternalCols, IRow, IRowKey, IRows, ISearchParams } from './table.type';
export class BixiTableComponent extends BixiPaginationListBase implements OnInit, OnChanges, OnDestroy {
get showFooter(): boolean {
if (this.frontPagination) {
return this._rows.length > this.pagination.pageSize;
} else {
return this.pagination.total > this.pagination.pageSize;
}
}
get total() {
return {
count: this.frontPagination ? this._rows.length : this.pagination.total
};
}
get checkboxCol() {
return this._cols.find(col => col.type === EColType.checkbox) as ICheckboxCol;
}
constructor(
private tableService: BixiTableService,
private tableUtilsService: BixiTableUtilsService,
private i18n: BixiI18nService,
private cdr: ChangeDetectorRef
) {
super();
}
subscription = new Subscription();
tableTotal: string;
configVersion = 'randomString';
_cols: IInternalCols = [];
_rows: IRows = [];
selectBoxWidth = '80px';
isIndeterminate = false;
isAllRowsChecked = false;
private selectableRows: IRow[] = [];
id: string;
cols: ICols = [];
rows: IRows = [];
loading = false;
frontPagination = false;
scroll: { x?: string | null; y?: string | null } = { x: null, y: null };
pageStartIndex = 1;
pageSizeOptions = PAGE_SIZE_OPTIONS;
pagination = { page: 1, pageSize: 10, total: 0 };
filterParams: IFilterParams = {};
selectedKeys: IRowKey[] = [];
paginationChange = new EventEmitter<IPagination>();
filterParamsChange = new EventEmitter<IFilterParams>();
search = new EventEmitter<ISearchParams>();
selectedKeysChange = new EventEmitter<IRowKey[]>();
ngOnInit() {
// 不使用 BixiPaginationListBase 中 ngOnInit()
this.subscription.add(
this.tableService.updateView$
.pipe(
filter(id => this.id === (id || this.id))
)
.subscribe(() => {
this.forceUpdate();
})
);
this.subscription.add(
this.i18n.localeChange
.subscribe(() => {
this.tableTotal = this.i18n.getLocaleData('table.total', this.total);
this.cdr.markForCheck();
})
);
}
ngOnChanges(changes: SimpleChanges) {
const { cols, filterParams, rows, pagination, selectedKeys } = changes;
if (cols || filterParams) {
this._cols = this.tableUtilsService.genCols(
cols?.currentValue || this.cols,
filterParams?.currentValue || this.filterParams
);
}
if (rows || selectedKeys) {
this._rows = this.tableUtilsService.genRows(
rows?.currentValue || this.rows,
this._cols,
selectedKeys?.currentValue || this.selectedKeys
);
this.checkSelectedStatus();
}
if (pagination) {
this.pagination = pagination.currentValue;
this.tableTotal = this.i18n.getLocaleData('table.total', this.total);
}
}
onFilterChange(queryKey: string, val: NzSafeAny) {
const filterParams = this.filterParams;
if (isNull(val)) {
delete filterParams[queryKey];
} else {
filterParams[queryKey] = !Array.isArray(val) ? [val] : val;
}
this.filterParamsChange.emit(filterParams);
// sort 会影响数据的长度,这里应该重置到第一页
// BAD SMELL!!
this.onResetPagination();
this.onSearch();
}
onSortChange(sortKey: string, val: NzSafeAny) {
const filterParams = this.filterParams;
if (isNull(val)) {
delete filterParams[sortKey];
} else {
filterParams[sortKey] = val;
}
this.filterParamsChange.emit(filterParams);
this.onSearch();
}
onSearch() {
this.paginationChange.emit(this.pagination);
this.search.emit({
filterParams: this.filterParams,
pagination: this.pagination
});
}
onRowSelectedChange({ key, selected }: { key: IRowKey, selected: boolean }) {
const selectedKeys = selected ? [...this.selectedKeys, key] : this.selectedKeys.filter(k => key !== k);
this.selectedKeysChange.emit(selectedKeys);
}
onSelectAll(selected: boolean) {
const changedKeys = this.selectableRows.map(row => row[this.checkboxCol.key]);
const selectedKeys = this.tableUtilsService.updateSelectedKeys(selected, this.selectedKeys, changedKeys);
this.selectedKeysChange.emit(selectedKeys);
}
checkSelectedStatus() {
this.selectableRows = this._rows.filter(row => row._selectable);
this.isIndeterminate = this.selectableRows.find(row => row._selected) && this.selectableRows.find(row => !row._selected);
this.isAllRowsChecked = this.selectableRows.length > 0 && this.selectableRows.every(row => row._selected);
}
private forceUpdate() {
this._cols = this.tableUtilsService.genCols(this.cols, this.filterParams);
this.configVersion = new Date().getMilliseconds().toString();
this.cdr.detectChanges();
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}