@siberiaweb/components
Version:
183 lines (182 loc) • 5.63 kB
JavaScript
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;