bricks/bricks/dynamicaccordion.js

240 lines
6.4 KiB
JavaScript
Raw Normal View History

2024-02-26 18:22:18 +08:00
var bricks = window.bricks || {};
bricks.PageContent = class extends bricks.Layout {
constructor(opts){
super(opts);
}
}
bricks.AccordionItem = class extends bricks.Layout {
constructor(opts){
super(opts);
this.set_css('accordion-item');
}
}
bricks.AccordionHeader = class extends bricks.Layout {
constructor(opts){
super(opts);
this.set_css('accordion-item-header');
}
}
bricks.DynamicAccordion = class extends bricks.VScrollPanel {
/*
{
"title":
"description",
"data_url",
"content_url"
"content_view"
"cache_limit",
"page_rows",
"header":
"record_view"
"record_show_field":
}
*/
constructor(opts){
super(opts);
this.set_css("accordion");
this.element = this.dom_element;
this.dataUrl = this.opts.data_url;
this.base_params = opts.params || {};
this.rows = parseInt(this.opts.page_rows);
this.lastPage = null;
this.contentUrl = this.opts.content_url;
this.pages = new Map(); // 用于存储已加载的页面数据
this.pageContents = new Map(); // 用于存储已加载的页面内容
this.active_content = null;
this.loading = false;
this.cacheLimit = this.opts.cache_limit;
if (this.opts.content_view){
this.content_view_tmpl = JSON.stringify(this.opts.content_view);
}
if (this.opts.record_view){
this.record_view_tmpl = JSON.stringify(this.opts.record_view);
}
this.bind('min_threshold', this.load_previous_page.bind(this));
this.bind('max_threshold', this.load_next_page.bind(this));
this.render();
}
render(params) {
this.clear_widgets();
this.pages = new Map(); // 用于存储已加载的页面数据
this.pageContents = new Map(); // 用于存储已加载的页面内容
params = params || {};
this.params = bricks.extend(this.base_params, params);
this.loadPage(1);
}
async loadPage(page) {
if (this.loading){
return;
}
this.loading = true;
// 检查页面是否在缓存中
if (! this.pages.has(page)) {
var jc = new bricks.HttpJson();
var params = bricks.extend({}, this.params);
params = bricks.extend(params,{
page:page,
rows:this.rows
});
var d = await jc.get(this.dataUrl,{params:params});
if (!d){
console.log(this.dataUrl,{params:params}, 'error');
this.loading = false;
return;
}
var data = d.rows;
this.lastPage = Math.ceil(d.total / this.rows);
this.pages.set(page, data); // 将数据缓存起来
await this.renderAccordionItems(data, page);
// 检查缓存是否已满
if (this.pages.size > this.cacheLimit) {
// 删除当前页最远的一页
var max, min;
var pages = Array.from(this.pages.keys());
max = Math.max(...pages);
min = Math.min(...pages);
const farthestPage = page == max? min : max;
var w = this.pageContents.get(farthestPage);
this.remove_widget(w);
this.pages.delete(farthestPage);
this.pageContents.delete(farthestPage);
}
var pages = Array.from(this.pages.keys());
if (page == Math.min(pages)){
this.scrollY = 1 / pages.length;
if (this.scrollY == 1){
this.scrollY = 0;
}
} else {
this.scrollY = (pages.length - 1) / pages.length;
}
}
this.loading = false;
return;
}
async renderAccordionItems(data, page) {
const pageContent = new bricks.PageContent({height:"auto"});
pageContent.page = page;
for (var i=0;i<data.length;i++){
const record = data[i];
const item = new bricks.AccordionItem({});
const header = new bricks.AccordionHeader({});
if (this.opts.record_view){
var w;
w = await bricks.widgetBuildWithData(this.record_view_tmpl,
header, record);
if (w){
header.add_widget(w);
} else {
console.log('bricks.widgetBuildWithData(), tmpl=', this.record_view_tmpl, 'record=', record);
}
}
header.textContent = record.title; // 使用数据记录的标题字段
var content = new bricks.VBox({
height:'auto',
display:'none'
});
content.set_css('accordion-item-content');
content.hide();
header.bind('click', this.toggle_content.bind(this, content, record));
item.add_widget(header);
item.add_widget(content);
pageContent.add_widget(item);
};
this.pageContents.set(page, pageContent);
var pages = Array.from(this.pages.keys());
if (page == Math.min(...pages)){
this.add_widget(pageContent, 0);
} else {
this.add_widget(pageContent);
}
}
async toggle_content(content, record, event){
if (this.active_content){
if (this.active_content != content){
this.active_content.clear_widgets();
this.active_content.hide();
this.active_content = null;
}
}
content.toggle_hide();
if (content.dom_element.style.display == 'none'){
console.log('content just collapsed');
content.clear_widgets();
this.active_content = null;
return;
}
var jc = new bricks.HttpJson();
var w;
if (this.content_view_tmpl){
w = await bricks.widgetBuildWithData(this.content_view_tmpl,
content, record);
} else if (this.contentUrl){
var url = this.contentUrl;
var params = {
'id':record.id
}
var desc = await jc.get(url, {params:params});
w = await bricks.widgetBuild(desc, content);
}
if (w){
content.add_widget(w);
this.active_content = content;
} else {
this.active_content = null;
content.hide();
}
}
get_load_page(dir){
var pages = Array.from(this.pages.keys());
if (dir=='up'){
var page = Math.min(...pages);
console.log('page=', page, pages, 'dir=', dir);
return page - 1;
} else {
var page = Math.max(...pages);
console.log('page=', page, pages, 'dir=', dir);
return page + 1;
}
}
async load_previous_page(){
var pages = Array.from(this.pages.keys());
var page = this.get_load_page('up');
if (page > 0){
await this.loadPage(page);
console.log('page loaded, page=', page);
} else {
var pages = Array.from(this.pages.keys());
console.log('page NOT loaded, page=', page,
'lastPage=', this.lastPage,
'rows=', this.rows,
'cacheLimit=', this.cacheLimit,
'buffered page=', pages.length);
}
}
async load_next_page(){
var pages = Array.from(this.pages.keys());
var page = this.get_load_page('down');
if (page <= this.lastPage){
await this.loadPage(page);
console.log('page Loaded, page=', page);
} else {
console.log('page=', page,
'lastPage=', this.lastPage,
'rows=', this.rows,
'cacheLimit=', this.cacheLimit,
'buffered page=', pages);
}
}
}
bricks.Factory.register('DynamicAccordion', bricks.DynamicAccordion);