UNPKG

@siberiaweb/components

Version:
183 lines (182 loc) 5.63 kB
import CSS from "./CSS"; import CustomGrid from "../custom-grid/CustomGrid"; /** * Бесконечная сетка. * * @template TRecord Тип записи. */ export default class EndlessGrid extends CustomGrid { /** * Конструктор. */ constructor() { super(); /** * Количество записей, загружаемых за один раз. */ this._loadRecordCount = EndlessGrid.DEFAULT_LOAD_RECORD_COUNT; /** * Сетевой запрос. */ this.httpRequest = null; /** * Страница для загрузки данных. */ this.page = 1; /** * Признак, что все данные загружены. */ this.completed = false; /** * Обработчик загрузки данных. */ this.onLoad = null; } /** * Наблюдаемые атрибуты. */ static get observedAttributes() { return CustomGrid.observedAttributes.concat([ EndlessGrid.ATTR_LOAD_RECORD_COUNT ]); } /** * @override */ firstConnectedCallback() { super.firstConnectedCallback(); this.classList.add(CSS.ENDLESS_GRID); let scrollTop = 0; this.addEventListener("scroll", () => { if (this.scrollTop !== scrollTop) { scrollTop = this.scrollTop; if ((scrollTop > 0) && ((this.clientHeight + scrollTop) >= this.scrollHeight)) { this.load(); } } }); } /** * Обработка изменения атрибута "load-record-count". * * @param newValue Новое значение. */ attrLoadRecordCountChange(newValue) { let value = newValue === null ? EndlessGrid.DEFAULT_LOAD_RECORD_COUNT : parseInt(newValue); if (isNaN(value)) { value = EndlessGrid.DEFAULT_LOAD_RECORD_COUNT; } if (value < 1) { value = 1; } this._loadRecordCount = value; } /** * @override */ attributeChangedCallback(name, oldValue, newValue) { super.attributeChangedCallback(name, oldValue, newValue); if (name === EndlessGrid.ATTR_LOAD_RECORD_COUNT) { this.attrLoadRecordCountChange(newValue); } } /** * Загрузка данных. * * @throws Error Если не указан обработчик загрузки данных. */ load() { if (this.completed) { return; } if (this.onLoad === null) { throw new Error("Не указан обработчик загрузки данных."); } if (this.httpRequest !== null) { this.httpRequest.abort(); } let httpRequest = this.onLoad(this.page, this.loadRecordCount) .onBeforeSend(() => { if ((this.httpRequest !== null) && (this.httpRequest !== httpRequest)) { return; } this.loading = true; }) .onComplete(() => { if ((this.httpRequest !== null) && (this.httpRequest !== httpRequest)) { return; } this.loading = false; }) .onSuccess((response) => { if ((this.httpRequest !== null) && (this.httpRequest !== httpRequest)) { return; } response.json().then((data) => { this.addDataSet(data); }); }); this.httpRequest = httpRequest; httpRequest.send(); } /** * Начало загрузки данных - очистка таблицы и загрузка данных с первой страницы. */ beginLoading() { this.clear(); this.completed = false; this.page = 1; this.load(); } /** * @override */ sort(col) { super.sort(col); this.beginLoading(); } /** * @override */ addDataSet(dataSet) { if (dataSet.length < this.loadRecordCount) { this.completed = true; } else { this.page++; } super.addDataSet(dataSet); } /** * Получение количества записей, загружаемых за один раз. */ get loadRecordCount() { return this._loadRecordCount; } /** * Установка количества записей, загружаемых за один раз. * * @param value Значение. */ set loadRecordCount(value) { this.setAttribute(EndlessGrid.ATTR_LOAD_RECORD_COUNT, value.toString()); } /** * Получение страницы для загрузки данных. */ getPage() { return this.page; } } /** * Наименование компонента. */ EndlessGrid.COMPONENT_NAME = "sw-endless-grid"; /** * Количество записей, загружаемых за один раз. */ EndlessGrid.ATTR_LOAD_RECORD_COUNT = "load-record-count"; /** * Количество записей, загружаемых за один раз по умолчанию. */ EndlessGrid.DEFAULT_LOAD_RECORD_COUNT = 100;