bugfix
This commit is contained in:
parent
1e6c4105aa
commit
3045033cf3
@ -4,7 +4,7 @@ SOURCES=" page_data_loader.js factory.js uitypesdef.js utils.js uitype.js \
|
||||
markdown_viewer.js video.js audio.js toolbar.js tab.js \
|
||||
input.js registerfunction.js button.js accordion.js \
|
||||
tree.js multiple_state_image.js dynamiccolumn.js form.js message.js conform.js \
|
||||
paging.js datagrid.js dataviewer.js iframe.js \
|
||||
paging.js datagrid.js iframe.js \
|
||||
floaticonbar.js miniform.js wterm.js dynamicaccordion.js \
|
||||
llm_dialog.js websocket.js datarow.js tabular.js "
|
||||
echo ${SOURCES}
|
||||
|
@ -1,258 +0,0 @@
|
||||
var bricks = window.bricks || {};
|
||||
|
||||
bricks.DataViewer = class extends bricks.VScrollPanel {
|
||||
/*
|
||||
{
|
||||
"title":
|
||||
"description",
|
||||
"data_url",
|
||||
"mobile_cols":
|
||||
"content_view"
|
||||
"has_content",
|
||||
"content_toggle_field"
|
||||
"cache_page_limit",
|
||||
"page_rows",
|
||||
"header":
|
||||
"record_view"
|
||||
}
|
||||
*/
|
||||
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.cachePageLimit = this.opts.cache_page_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.oldscrollY = null;
|
||||
this.render();
|
||||
}
|
||||
create_container(){
|
||||
this.container = new Filler();
|
||||
}
|
||||
|
||||
render(params) {
|
||||
bricks.debug('params=', params, 'render() called');
|
||||
this.clear_widgets();
|
||||
this.pages = new Map(); // 用于存储已加载的页面数据
|
||||
this.pageContents = new Map(); // 用于存储已加载的页面内容
|
||||
params = params || {};
|
||||
this.params = bricks.extend(this.base_params, params);
|
||||
this.loadPage(1);
|
||||
this.dom_element.scrollTop = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
async loadPage(page) {
|
||||
// 检查页面是否在缓存中
|
||||
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){
|
||||
bricks.debug(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.cachePageLimit) {
|
||||
// 删除当前页最远的一页
|
||||
var max, min;
|
||||
var pages = Array.from(this.pages.keys());
|
||||
max = Math.max(...pages);
|
||||
min = Math.min(...pages);
|
||||
const farthestPage = page == max? min : max;
|
||||
this.delete_page(farthestPage);
|
||||
this.pages.delete(farthestPage);
|
||||
}
|
||||
} else {
|
||||
bricks.debug(page, 'already n buffer, do not thing');
|
||||
}
|
||||
return;
|
||||
}
|
||||
is_max_page(page){
|
||||
const pages = Array.from(this.pages.keys());
|
||||
return page == Math.max(...pages);
|
||||
}
|
||||
is_min_page(page){
|
||||
const pages = Array.from(this.pages.keys());
|
||||
return page == Math.min(...pages);
|
||||
}
|
||||
async renderRecords(data, page) {
|
||||
var pos;
|
||||
for (var i=0;i<data.length;i++){
|
||||
if (this.is_max_page(page)){
|
||||
pos = -1;
|
||||
} else {
|
||||
pos = 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 {
|
||||
bricks.debug('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, header, content, record));
|
||||
item.add_widget(header);
|
||||
item.add_widget(content);
|
||||
item.set_attribute('data-page', page);
|
||||
this.add_widget(item, pos);
|
||||
if (pos >= 0){
|
||||
this.dom_element.scrollTop += item.get_height();
|
||||
} else {
|
||||
this.dom_element.scrollTop -= item.get_height();
|
||||
}
|
||||
};
|
||||
}
|
||||
delete_page(page){
|
||||
var items = this.dom_element.querySelectorAll('[data-page="' + page + '"]');
|
||||
for (var i=0;i<items.length;i++) {
|
||||
var w = items[i].bricks_widget;
|
||||
this.remove_widget(w);
|
||||
}
|
||||
}
|
||||
|
||||
async toggle_content(header, content, record, event){
|
||||
var h = this.dom_element.offsetHeight - 3 * header.dom_element.offsetHeight;
|
||||
content.set_style('height', h + 'px');
|
||||
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'){
|
||||
bricks.debug('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 (pages.length == 0){
|
||||
return 1;
|
||||
}
|
||||
if (dir=='up'){
|
||||
var page = Math.min(...pages);
|
||||
bricks.debug('page=', page, pages, 'dir=', dir);
|
||||
return page - 1;
|
||||
} else {
|
||||
var page = Math.max(...pages);
|
||||
bricks.debug('page=', page, pages, 'dir=', dir);
|
||||
return page + 1;
|
||||
}
|
||||
}
|
||||
async load_previous_page(){
|
||||
if (this.loading){
|
||||
bricks.debug('this.loading is set, do not thing');
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
try {
|
||||
var page = this.get_load_page('up');
|
||||
if (page > 0){
|
||||
await this.loadPage(page);
|
||||
var pages = Array.from(this.pages.keys());
|
||||
bricks.debug('load_previous_page():page loaded, page=', page, pages);
|
||||
} else {
|
||||
var pages = Array.from(this.pages.keys());
|
||||
bricks.debug('page NOT loaded, page=', page,
|
||||
'lastPage=', this.lastPage,
|
||||
'rows=', this.rows,
|
||||
'cachePageLimit=', this.cachePageLimit,
|
||||
'buffered page=', pages.length);
|
||||
}
|
||||
} catch(e){
|
||||
bricks.debug('error happened', e);
|
||||
}
|
||||
this.loading = false;
|
||||
}
|
||||
async load_next_page(){
|
||||
if (this.loading){
|
||||
bricks.debug('this.loading is set, do not thing');
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
try {
|
||||
var page = this.get_load_page('down');
|
||||
if (page <= this.lastPage){
|
||||
await this.loadPage(page);
|
||||
var pages = Array.from(this.pages.keys());
|
||||
bricks.debug('load_next_page():page Loaded, page=', page, pages);
|
||||
} else {
|
||||
var pages = Array.from(this.pages.keys());
|
||||
bricks.debug('page=', page,
|
||||
'lastPage=', this.lastPage,
|
||||
'rows=', this.rows,
|
||||
'cachePageLimit=', this.cachePageLimit,
|
||||
'buffered page=', pages);
|
||||
}
|
||||
} catch (e){
|
||||
bricks.debug('error happened', e);
|
||||
}
|
||||
this.loading = false;
|
||||
bricks.debug('load_next_page() finished');
|
||||
}
|
||||
}
|
||||
bricks.Factory.register('DynamicAccordion', bricks.DynamicAccordion);
|
@ -51,3 +51,5 @@ bricks.DynamicColumn = class extends bricks.Layout {
|
||||
this.set_style('gap', gap + 'px');
|
||||
}
|
||||
}
|
||||
|
||||
bricks.Factory.register('DynamicColumn', bricks.DynamicColumn);
|
||||
|
3
docs/cn/widgethierarchy.md
Normal file
3
docs/cn/widgethierarchy.md
Normal file
@ -0,0 +1,3 @@
|
||||
# 控件继承树
|
||||
|
||||
|
@ -4,9 +4,64 @@ Bricks内置许多的显示控件,所有显示控件都继承自JsWidget,容
|
||||
# 控件继承树
|
||||
|
||||
# 控件清单
|
||||
* [JsWidget](widgets/jswidget.md): 祖先控件,对应于<div>元素
|
||||
* [Accordion](widgets/accordion.md):可折叠控件
|
||||
* [AudioPlayer](widgets/audioplayer.md):音频播放器
|
||||
* [AudioRecorder](widgets/audiorecorder.md)
|
||||
* [SttClient](widgets/sttclient.md)
|
||||
* [Button](widgets/button.md)
|
||||
* [Conform](widgets/conform.md)
|
||||
* [DataGrid](widgets/datagrid.md)
|
||||
* [DataRow](widgets/datarow.md)
|
||||
* [DynamicAccordion](widgets/dynamicaccordion.md)
|
||||
* [DynamicColumn](widgets/dynamiccolums.md)
|
||||
* [IconBar](widgets/iconbar.md)
|
||||
* [IconTextBar](widgets/icontextbar.md)
|
||||
* [FloatIconBar](widgets/floaticonbar.md)
|
||||
* [FloatIconTextBar](widgets/floaticontextbar.wd)
|
||||
* [Form](widgets/form.md)
|
||||
* [Html](widgets/html.md)
|
||||
* [Iframe](widgets/iframe.md)
|
||||
* [Image](widgets/image.md)
|
||||
* [Icon](widgets/icon.md)
|
||||
* [BlankIcon](widgets/blankicon)
|
||||
* [HBox](widgets/hbox.md)
|
||||
* [FHBox](widgets/fhbox.md)
|
||||
* [VBox](widgets/vbox.md)
|
||||
* [FVBox](widgets/fvbox.md)
|
||||
* [Filler](widgets/filler.md)
|
||||
* [LlmDialog](widgets/llmdialog.md)
|
||||
* [MarkdownViewer](widgets/markdownviewer.md)
|
||||
* [MdWidget](widgets/mdwidget.md)
|
||||
* [Menu](widgets/menu.md)
|
||||
* [Message](widgets/menu.md)
|
||||
* [Error](widgets/menu.md)
|
||||
* [PopupForm](widgets/menu.md)
|
||||
* [MiniForm](widgets/menu.md)
|
||||
* [Modal](widgets/menu.md)
|
||||
* [ModalForm](widgets/menu.md)
|
||||
* [MultipleStateImage](widgets/menu.md)
|
||||
* [MultipleStateIcon](widgets/menu.md)
|
||||
* [Running](widgets/menu.md)
|
||||
* [VScrollPanel](widgets/menu.md)
|
||||
* [HScrollPanel](widgets/menu.md)
|
||||
* [TabPanel](widgets/menu.md)
|
||||
* [Tabular](widgets/menu.md)
|
||||
* [Toolbar](widgets/menu.md)
|
||||
* [Tree](widgets/menu.md)
|
||||
* [EditableTree](widgets/menu.md)
|
||||
* [Video](widgets/menu.md)
|
||||
* [WebSocket](widgets/menu.md)
|
||||
* [Tooltip](widgets/menu.md)
|
||||
* [Text](widgets/menu.md)
|
||||
* [Title1](widgets/menu.md)
|
||||
* [Title2](widgets/menu.md)
|
||||
* [Title3](widgets/menu.md)
|
||||
* [Title4](widgets/menu.md)
|
||||
* [Title5](widgets/menu.md)
|
||||
* [Title6](widgets/menu.md)
|
||||
* [Wterm](widgets/menu.md)
|
||||
|
||||
* [JsWidget](widgets/jswidget.md): 祖先控件,对应于<div>元素
|
||||
* [Button](widgets/button.md):按钮控件
|
||||
* [DataGrid](widgets/datagrid.md):数据表格控件
|
||||
* [Form](widgets/form.md):输入表单控件
|
||||
|
Loading…
Reference in New Issue
Block a user