UNPKG

@rdkmaster/jigsaw-labs

Version:

Jigsaw, the next generation component set for RDK

480 lines (479 loc) 22.8 kB
import { HttpClient } from "@angular/common/http"; import "rxjs/add/operator/map"; import 'rxjs/add/operator/debounceTime'; import { AbstractGeneralCollection } from "./general-collection"; import { DataFilterInfo, DataSortInfo, HttpClientOptions, IFilterable, IPageable, IServerSidePageable, ISlicedData, ISortable, PagingInfo, SortAs, SortOrder, ViewportData } from "./component-data"; /** * 代表表格数据矩阵`TableDataMatrix`里的一行 */ export declare type TableMatrixRow = any[]; /** * 代表表格的列头描述,其个数需要与表格数据`TableDataMatrix`的列数相等并一一对应 * 这里的数据将会显示在界面上,需要确保对他们进行国际化处理 */ export declare type TableDataHeader = string[]; /** * 代表表格的列头字段,其个数需要与表格数据`TableDataMatrix`的列数相等并一一对应, * 并且不能重复,建议以数据库表字段对应起来。 * 这些数据对表格识别列至关重要,无效的、重复的值将会被忽略 */ export declare type TableDataField = string[]; /** * 代表表格的数据区,是一个二维矩阵。矩阵的列数需要和`TableDataField`以及`TableDataHeader`的个数一致且一一对应。 */ export declare type TableDataMatrix = TableMatrixRow[]; /** * 原始表格数据结构,Jigsaw的表格组件接收的唯一数据结构。 */ export declare class RawTableData { /** * 表格数据的字段序列,这个序列决定了`JigsawTable`实际渲染出来哪些列。无效、重复的字段将被抛弃。 */ field: TableDataField; /** * 表格的列头,这里的文本将会直接显示在界面上,请确保他们已经被正确国际化过。 */ header: TableDataHeader; /** * 表格的数据,是一个二维数组。 */ data: TableDataMatrix; [property: string]: any; } /** * 表格数据的基类,应用一般无需直接使用这个类。 * * 关于Jigsaw数据体系详细介绍,请参考`IComponentData`的说明 */ export declare class TableDataBase extends AbstractGeneralCollection<any> { /** * 表格的数据,是一个二维数组。 * @type {TableDataMatrix} */ data: TableDataMatrix; /** * 表格数据的字段序列,这个序列决定了`JigsawTable`实际渲染出来哪些列。无效、重复的字段将被抛弃。 * @type {TableDataField} */ field: TableDataField; /** * 表格的列头,这里的文本将会直接显示在界面上,请确保他们已经被正确国际化过。 * @type {TableDataHeader} */ header: TableDataHeader; /** * 给出`data`的数据结构是否和`RawTableData`一致,即`data`是否是一个合法的表格数据。 * 注意此方法并非使用类的血缘关系来判断,而是通过数据结构的特征来判断。 * * @param data * @return {boolean} */ static isTableData(data: any): boolean; constructor(/** * 表格的数据,是一个二维数组。 * @type {TableDataMatrix} */ data?: TableDataMatrix, /** * 表格数据的字段序列,这个序列决定了`JigsawTable`实际渲染出来哪些列。无效、重复的字段将被抛弃。 * @type {TableDataField} */ field?: TableDataField, /** * 表格的列头,这里的文本将会直接显示在界面上,请确保他们已经被正确国际化过。 * @type {TableDataHeader} */ header?: TableDataHeader); /** * 参考 `TableData.isTableData` * * @param data * @return {boolean} */ protected isDataValid(data: any): boolean; protected ajaxSuccessHandler(data: any): void; fromObject(data: any): TableDataBase; protected static arrayAppend(dest: any[], source: any): void; /** * 参考 `TableData.toArray` * @returns {any[]} */ toArray(): any[]; /** * 清空此对象上的所有数据,避免潜在的内存泄露风险 */ clear(): void; destroy(): void; /** * 在当前表格数据的`column`位置处插入一个新列。常常用于表格数据的`dataReviser`函数内,对服务端返回的数据做调整时用到。 * * @param {number} column 新列所在的位置 * @param cellData 新列的单元格的值,新插入列的每个单元格的值都相同。 * @param {string} field 新插入列的字段,不允许与已有字段相同。 * @param {string} header 新插入列的列头信息。 */ insertColumn(column: number, cellData: any, field: string, header: string): void; /** * @param {number} column * @param {any[]} cellDatas 新列的单元格的值,每个单元格的值与此数组的元素一一对应 * @param {string} field * @param {string} header */ insertColumn(column: number, cellDatas: any[], field: string, header: string): void; /** * 删除当前表格数据`column`位置处的列。常常用于表格数据的`dataReviser`函数内,对服务端返回的数据做调整时用到。 * * @param {number} column 待删除的列索引 * @returns {TableData} 返回删除后的`TableData`对象,当前对象不变 */ removeColumn(column: number): TableData; } /** * 这是最基础的表格数据对象,只具备最基本的表格数据展示能力,无法分页, * 一般用于以下类型的表格数据无法满足需求时,实现自定义表格数据的基础数据。 * * - {@link PageableTableData} 适用于需要在服务端进行分页、过滤、排序的场景,这是最常用的一个数据对象; * - {@link LocalPageableTableData} 适用于需要在浏览器本地进行分页、过滤、排序的场景,受限于数据量,不是很常用; * - {@link BigTableData} 适用于海量数据的展示场景,它可以做到在常数时间内展示**任意量级**的数据。 * * 建议尽可能的挑选以上类型的表格数据,以减少定制化的开发工作量。 * * 表格数据是Jigsaw数据体系中的一个重要分支,关于Jigsaw数据体系详细介绍,请参考`IComponentData`的说明 */ export declare class TableData extends TableDataBase implements ISortable, IFilterable { /** * 将`RawTableData`对象转为`TableData`对象。 * * 注意:源对象的 `data` / `field` / `header` 属性会被**浅拷贝**到目标`TableData`对象中。 * * @param rawData 结构为 `RawTableData` 的json对象 * @returns {TableData} 返回持有输入数据的`TableData`实例 */ static of(rawData: any): TableData; /** * 将一个`RawTableData`对象转为一个json对象数组。 * * 虽然`RawTableData`这样的数据结构有很多好处,比如利于网络传输,利于表格展示,在占用更小的内存等, * 但是由于这不是一个典型的json对象结构,因此如果需要将它使用到表格以外的场合,则会产生一些麻烦。 * 可以通过这个方法将它转换为一个典型的json对象。 * * 原始原始数据: * * ``` * { * data: [ * [11, 12, 13], * [21, 22, 23], * [31, 32, 33] * ], * field: ['field1', 'field2', 'field3'], * header: ['header1', 'header2', 'header3'] * } * ``` * * 将被转换为: * * ``` * [ * {field1: 11, field2: 12, field3: 13}, * {field1: 21, field2: 22, field3: 23}, * {field1: 31, field2: 32, field3: 33}, * ] * ``` * * @param rawData * @returns {any[]} */ static toArray(rawData: any): any[]; sortInfo: DataSortInfo; sort(compareFn?: (a: any[], b: any[]) => number): void; sort(as: SortAs, order: SortOrder, field: string | number): void; sort(sort: DataSortInfo): void; /** * 对输入的数据进行排序 * * @param {TableDataMatrix} data 输入的数据 * @param {SortAs | DataSortInfo | Function} as 排序参数 * @param {SortOrder} order 排序顺序 * @param {string | number} field 排序字段 */ protected sortData(data: TableDataMatrix, as: SortAs | DataSortInfo | Function, order?: SortOrder, field?: string | number): void; filterInfo: DataFilterInfo; filter(compareFn: (value: any, index: number, array: any[]) => any, thisArg?: any): any; filter(term: string, fields?: (string | number)[]): void; filter(term: DataFilterInfo): void; destroy(): void; } /** * 这是实际使用时做常用的表格数据对象,它具备服务端分页、服务端排序、服务端过滤能力。 * 详细用法请参考[这个demo]($demo=table/pageable)。 * * 注意:需要有一个统一的具备服务端分页、服务端排序、服务端过滤能力的REST服务配合使用, * 更多信息请参考`PagingInfo.pagingServerUrl` * * 相关的表格数据对象: * - {@link PageableTableData} 适用于需要在服务端进行分页、过滤、排序的场景,这是最常用的一个数据对象; * - {@link LocalPageableTableData} 适用于需要在浏览器本地进行分页、过滤、排序的场景,受限于数据量,不是很常用; * - {@link BigTableData} 适用于海量数据的展示场景,它可以做到在常数时间内展示**任意量级**的数据。 * * 表格数据是Jigsaw数据体系中的一个重要分支,关于Jigsaw数据体系详细介绍,请参考`IComponentData`的说明 */ export declare class PageableTableData extends TableData implements IServerSidePageable, IFilterable, ISortable { http: HttpClient; /** * 当前数据对象的查询参数,注意这个参数在进行分页、排序、过滤的时候,都会带给服务端。 * 提示:可将这个对象对应属性通过双向绑定的方式提供给查询条件的视图,这样在视图上数据更新了后,这里的值就可立即得到更新,例如: * * ``` * <j-input [(value)]="tableData?.sourceRequestOptions?.params?.value"> * </j-input> * ``` * * 或者在需要获取数据之前,一次性通过`updateDataSource`来更新这个对象。 */ sourceRequestOptions: HttpClientOptions; pagingInfo: PagingInfo; private _filterSubject; private _sortSubject; constructor(http: HttpClient, requestOptionsOrUrl: HttpClientOptions | string); private _initSubjects(); /** * 在使用此方法之前,请先阅读一下`sourceRequestOptions`的说明,你需要先了解它的作用之后, * 才能够知道如何恰当的使用这个方法来更新`sourceRequestOptions`。 * * 这个方法除了更新`sourceRequestOptions`以外,还会自动重置`pagingInfo`的各个参数, * 以及清空`filterInfo`和`sortInfo`。 * * @param {HttpClientOptions} options 数据源的结构化信息 */ updateDataSource(options: HttpClientOptions): void; /** * @param {string} url 包含查询参数的url,只能通过GET访问它。 */ updateDataSource(url: string): void; fromAjax(url?: string): void; fromAjax(options?: HttpClientOptions): void; private _ajax(); private _updatePagingInfo(data); filter(compareFn: (value: any, index: number, array: any[]) => any, thisArg?: any): any; filter(term: string, fields?: string[] | number[]): void; filter(term: DataFilterInfo): void; sort(compareFn?: (a: any[], b: any[]) => number): void; sort(as: SortAs, order: SortOrder, field: string | number): void; sort(sort: DataSortInfo): void; changePage(currentPage: number, pageSize?: number): void; changePage(info: PagingInfo): void; firstPage(): void; previousPage(): void; nextPage(): void; lastPage(): void; destroy(): void; } export declare class TableViewportData extends ViewportData { private _bigTableData; maxWidth: number; maxHeight: number; constructor(_bigTableData: BigTableData); private _rows; rows: number; private _columns; columns: number; private _verticalTo; verticalTo: number; setVerticalPositionSilently(value: number): void; private _horizontalTo; horizontalTo: number; setHorizontalPositionSilently(value: number): void; private _sliceData(); width: number; height: number; } /** * `BigTableData`是Jigsaw的表格呈现海量数据时的一个解决方案,**它能够以常数时间处理任何量级的数据**。 * * #### 适用的场景 * * 这个方法目前适用于海量对静态数据做展示的场景,暂时不支持对海量数据展示的同时提供**有状态**的交互能力, * 即`BigTableData`暂不支持与可编辑的渲染器(如`JigsawInput`/`JigsawCheckbox`/`JigsawSwitch`等)一起使用, * 如果你有这样的需求,那请给我们[提Issue](https://github.com/rdkmaster/jigsaw/issues/new),我会考虑支持。 * * 此外,这个解决方案也充分考虑到了用户在IE11等低性能浏览器上浏览海量数据的体验,针对性的做了优化, * 你可以使用IE11打开这个demo看看它在低性能浏览器上的表现。 * * #### 原理 * * 原理非常简单,我们使用`BigTableData`这个数据对象将数据做切片处理后传递给表格呈现出来, * 表格控件无需处理所有数据,它始终只需要处理当前用户可视部分的数据,用户不可视部分的数据被忽略, * 这也就是`BigTableData`可以在常数时间处理任意量级的数据的原因了。 * `BigTableData`充分体现了表格彻底由数据驱动的优势。 * * #### 无分页浏览数据 * * 甚至,`BigTableData`还能够消除数据分页给浏览器数据带来的不便之处,进一步提升浏览数据的体验。 * * 我们都知道,海量的数据是不可能一下子全部从服务端读取到客户端里的,传统的解决方案是对数据做分页处理, * 页面上分批下载数据,用户分批查看数据,用户不得不等待两页数据切换带来的时延,这打断了用户浏览数据的过程,体验很差。 * * `BigTableData`在第一页数据下载完毕之后,在两三百ms之内就能够将数据呈现出来,用户开始浏览数据, * 随着用户将滚动条下移到接近本页数据尾部的时候,`BigTableData`自动在后台发起加载下一页数据的请求, * 当用户浏览完毕当前页数据的时候,`BigTableData`早就将下一页数据准备好了。 * 这样,用户浏览数据的过程没有因为加载数据而中断。 * * 考虑到内存的消耗,`BigTableData`默认只缓存3页数据: * * - 前一页; * - 当前页; * - 下一页; * * 超过部分将会从内存中清理掉,从而避免浏览器占用过高的内存导致用户电脑卡顿。缓存的页数越多体验越好, * 你可以根据实际情况调整`BigTableData`的`numCachedPages`属性来调整缓存的页数,设置为`0`则缓存所有。 * `BigTableData`至少缓存3页数据。 * * #### 不适用的场景 * * 正如前文所说,`BigTableData`目前暂时不适用于展示有状态的交互需求的场景,例如使用有编辑功能的渲染器就是典型的有状态的交互场景。 * 如果你有这样的需求,那请给我们[提Issue](https://github.com/rdkmaster/jigsaw/issues/new), * 将你碰到的场景和需求详细描述给我们。 * * #### 注意 * * `BigTableData`需要有一个统一的具备服务端分页、服务端排序、服务端过滤能力的REST服务配合使用, * 更多信息请参考`PagingInfo.pagingServerUrl`。 * * 如果你的服务端无法给提供一个统一的分页服务, * 则可以通过[Angular的拦截器](https://angular.cn/guide/http#intercepting-requests-and-responses)来模拟。 * `BigTableData`在需要获取下一页数据时,会将请求做一层包装后发给统一分页服务,实际的数据请求是在统一分页服务里完成的。 * 你需要做的事情是实现一个拦截器,将`BigTableData`发给统一分页服务的请求拦截下来,解析被拦截的请求里的实际请求参数, * 并将这些请求转发给实际提供数据的服务。 * * 相关的表格数据对象: * - {@link PageableTableData} 适用于需要在服务端进行分页、过滤、排序的场景,这是最常用的一个数据对象; * - {@link LocalPageableTableData} 适用于需要在浏览器本地进行分页、过滤、排序的场景,受限于数据量,不是很常用; * - {@link BigTableData} 适用于海量数据的展示场景,它可以做到在常数时间内展示**任意量级**的数据。 * * 表格数据是Jigsaw数据体系中的一个重要分支,关于Jigsaw数据体系详细介绍,请参考`IComponentData`的说明 */ export declare class BigTableData extends PageableTableData implements ISlicedData { http: HttpClient; readonly viewport: TableViewportData; /** * 缓存数据页数,这里的页指的是服务端单次返回的数据集,和传统服务端分页数据的概念是相同的。 * * 这个数值越大,表格数据浏览的体验更好,更流畅,但是需要占用的浏览器内存越多; * 相反的,给的数值越小,表格找服务端请求数据的机会越多,数据浏览体验下降,但是浏览器所需内存越小。 * 需要根据服务端性能以及单页数据量而定。最小值为3页。 * * @type {number} */ numCachedPages: number; /** * 当预加载的一页数据剩下未展示出来的记录数小于这个比例时,{@link BigTableData}会在后台悄悄发起下一页数据的加载, * 以确保用户将这一页数据浏览完时,可以在不被打断的前提下继续浏览下一页数据。这个参数的有效取值范围是0.01 ~ 0.99。 * * @type {number} */ fetchDataThreshold: number; /** * 和`busy`具有相同含义 * * @type {boolean} */ protected reallyBusy: boolean; constructor(http: HttpClient, requestOptionsOrUrl: HttpClientOptions | string); private _cache; /** * 当前缓存的数据 * * @returns {RawTableData} */ readonly cache: RawTableData; private _isCacheAvailable(); /** * 根据界面上滚动条滑动对缓冲的数据进行切片 */ protected sliceData(): void; scroll(verticalTo: number, horizontalTo?: number): void; vScroll(scrollTo: number): void; hScroll(scrollTo: number): void; /** * 检查缓冲区里的数据是否足够用,如果够用了,则会触发获取数据流程 * * @param {number} verticalTo */ protected checkCache(verticalTo: number): void; /** * `changePage`改用debounce之后,由于有debounce,`_busy`的值就不准了,只能自己维护这个状态 * * @type {boolean} * @private */ private _fetchingData; /** * 向服务端发起获取数据的请求 * * @param targetPage * @param verticalTo */ protected fetchData(targetPage: any, verticalTo: any): void; /** * 更新缓冲区 */ protected updateCache(): void; private _printPageError(); protected ajaxSuccessHandler(rawTableData: any): void; protected ajaxErrorHandler(error: any): void; private _updateViewPortSize(); /** * 这个属性为true时,表示{@link BigTableData}的预加载数据已经被浏览完,并且下一页数据还未取到。否则此值为false。 * 即只有在{@link BigTableData}真的很忙的时候,此属性才是true。 * * @returns {boolean} */ readonly busy: boolean; /** * @internal */ changePage(currentPage: number, pageSize?: number): void; /** * @internal */ changePage(info: PagingInfo): void; } /** * `LocalPageableTableData`具备浏览器本地内存中进行分页、排序、过滤能力, * 受限于浏览器内存的限制,无法操作大量的数据,建议尽量采用`PageableTableData`以服务端分页的形式展示数据。 * 详细用法请参考[这个demo]($demo=table/local-paging-data)。 * * 相关的表格数据对象: * - {@link PageableTableData} 适用于需要在服务端进行分页、过滤、排序的场景,这是最常用的一个数据对象; * - {@link LocalPageableTableData} 适用于需要在浏览器本地进行分页、过滤、排序的场景,受限于数据量,不是很常用; * - {@link BigTableData} 适用于海量数据的展示场景,它可以做到在常数时间内展示**任意量级**的数据。 * * 表格数据是Jigsaw数据体系中的一个重要分支,关于Jigsaw数据体系详细介绍,请参考`IComponentData`的说明 */ export declare class LocalPageableTableData extends TableData implements IPageable, IFilterable, ISortable { pagingInfo: PagingInfo; /** * 原始数据经过过滤后的数据,请勿直接操作这些数据,而是采用本类定义的各个api来操作他们。 */ filteredData: TableDataMatrix; /** * 原始数据,请勿直接操作这些数据,而是采用本类定义的各个api来操作他们。 */ originalData: TableDataMatrix; constructor(); fromObject(data: any): LocalPageableTableData; filter(callbackfn: (value: any, index: number, array: any[]) => any, thisArg?: any): any; filter(term: string, fields?: string[] | number[]): void; filter(term: DataFilterInfo): void; sort(compareFn?: (a: any, b: any) => number): any; sort(as: SortAs, order: SortOrder, field: string | number): void; sort(sort: DataSortInfo): void; private _updatePagingInfo(); changePage(currentPage: number, pageSize?: number): void; changePage(info: PagingInfo): void; private _setDataByPageInfo(); firstPage(): void; previousPage(): void; nextPage(): void; lastPage(): void; destroy(): void; }