bricks/docs/cn.old/cols.md
2025-11-19 12:30:39 +08:00

9.1 KiB
Raw Blame History

bricks.Cols 技术文档

模块bricks.Cols
继承自bricks.VBox
用途:用于展示分页数据的列式布局组件,支持滚动加载、点击事件、动态渲染记录等特性。


概述

bricks.Cols 是一个基于 VBox 布局容器构建的数据展示控件,专为高效展示大量可分页数据而设计。它通过垂直滚动加载前后页内容(懒加载),并以列的形式排列每条记录,适用于移动端和桌面端的响应式布局。

该组件常用于新闻列表、商品展示、用户卡片墙等场景。


继承结构

bricks.Widget
 └── bricks.Container
      └── bricks.Box
           └── bricks.VBox
                └── bricks.Cols

配置选项Constructor Options

参数 类型 说明
data_url String 获取数据的 API 地址,用于异步加载分页数据。
data_params Object 初始请求参数对象,在每次请求时合并发送。
data_method String 请求方法(如 "GET""POST"),默认由 PageDataLoader 决定。
page_rows Number 每页显示的数据行数。
cache_limit Number 缓存的最大页数,超出后自动清理旧页。
col_width String/Number 单个列的宽度CSS 格式,如 "200px")。
col_cwidth String 列的弹性宽度CSS flex 值,如 "1fr")。
mobile_cols Number 移动端每行显示的列数,默认为 2
record_view Object 记录项的视图配置,定义如何使用 widgetBuild 渲染单条数据。
title String 可选标题文本(支持国际化)。
description String 可选描述文本(支持 Markdown
toolbar Object 工具栏配置对象,将被构造成 bricks.Toolbar 实例。

事件Events

事件名 触发条件 参数
record_click 用户点击某条记录时触发 (recordData) — 当前记录的原始数据对象
command 工具栏发出命令时转发此事件(通过 dispatch 命令名称及参数

使用 .bind(event, handler) 方法监听这些事件。


属性Properties

属性 类型 描述
loader bricks.PageDataLoader 分页数据加载器实例,负责管理前后页数据获取与缓存。
container bricks.VScrollPanel 外层垂直滚动容器,监听滚动阈值以触发分页加载。
main bricks.DynamicColumn 实际存放记录项的动态列容器。
select_record Widget 当前选中的记录对应的 widget 实例。
loading Boolean 是否正在加载数据,防止重复请求。
title_w bricks.Title4 标题组件实例(如果设置了 title)。
desc_w bricks.MdWidget 描述组件实例(如果设置了 description)。
toolbar_w bricks.Toolbar 工具栏组件实例(如果设置了 toolbar)。

方法Methods

constructor(opts)

初始化 Cols 组件,并创建子组件结构。

流程说明:

  1. 调用父类构造函数。
  2. 初始化 PageDataLoader 加载器。
  3. 创建滚动容器 VScrollPanel 并绑定滚动边界事件。
  4. 根据配置添加标题、描述、工具栏。
  5. 创建主内容区域 DynamicColumn
  6. 延迟 0.5 秒调用 load_first_page() 加载首屏数据。

command_handle(event)

处理来自工具栏的命令事件,并将其转为 dispatch 派发出去。

this.toolbar_w.bind('command', this.command_handle.bind(this));

async handle_click(rw, event)

处理单个记录项的点击事件。

功能:

  • 阻止事件冒泡。
  • 取消上一个选中项的高亮样式。
  • 设置当前项为选中状态并添加 selected_record CSS 类。
  • 打印日志并派发 record_click 事件,携带 user_data

rw.user_data 存储的是该记录的原始数据对象。


async dataHandle(d)

处理从 loader 返回的数据包,并渲染到界面。

参数:

  • d: 数据对象,格式如下:
    {
      rows: [...],         // 数据数组
      add_page: Number,    // 添加到哪一页
      delete_page: Number, // (可选)需删除的页码(用于翻页替换)
      pos_rate: Number     // 滚动位置比例0~1
    }
    

行为逻辑:

  • 若是向前翻页(非最大页),则反转数据顺序以便插入顶部。
  • 使用 widgetBuild(record_view, parent, data) 动态生成每个记录 widget。
  • 绑定点击事件。
  • 设置 data-page 属性用于后续删除。
  • 插入至 main 容器开头或末尾。
  • 如有 delete_page,调用 delete_page() 清理旧页。

delete_page(page)

删除指定页码的所有 DOM 元素及其 widget。

实现方式:

  • 查询所有 [data-page="X"] 的元素。
  • 获取其关联的 bricks_widget 实例。
  • main 中移除对应 widget。

create_main_widget()

重新创建主内容区域(DynamicColumn),通常在刷新或重置布局时调用。

this.main = new bricks.DynamicColumn({
  width: "100%",
  col_cwidth: this.col_cwidth,
  mobile_cols: this.mobile_cols || 2
});

async show_with_data(data)

直接传入本地数据进行展示(绕过 data_url 请求)。

⚠️ 注意:目前代码中存在错误,应为 await this.load_first_page(params); 而不是 await load_first_page(params);

正确实现建议:

async show_with_data(data){
  this.data = data;
  this.data_url = null;
  await this.load_first_page(); // 不需要参数
}

async load_first_page(params)

加载第一页数据。

流程:

  1. 显示加载动画(Running 组件)。
  2. 检查是否已在加载中,避免重复请求。
  3. 合并 data_params 与传入的 params
  4. 调用 loader.loadData() 获取数据。
  5. 成功后清空主容器并调用 dataHandle(d)
  6. 出错时打印调试信息。
  7. 最终隐藏加载动画,释放锁。

async load_previous_page()

向上滚动触底时加载前一页。

  • 自动计算滚动位置并恢复。
  • 支持 pos_rate 定位。
  • 错误时仅输出 debug 日志。

async load_next_page()

向下滚动触底时加载下一页。

  • 类似于 load_previous_page,但加载下一页。
  • 注释掉的 scrollTop 表示暂未启用精确滚动定位。

内部机制

分页加载策略

利用 bricks.PageDataLoader 实现智能分页:

  • 支持双向分页(上一页 / 下一页)。
  • 支持缓存控制(cache_pages)。
  • 数据按“页”组织,可通过 data-page 属性追踪来源。

滚动加载触发

通过 VScrollPanel 的两个事件实现无限滚动:

事件 触发条件
min_threshold 滚动到顶部附近 → 加载前一页
max_threshold 滚动到底部附近 → 加载下一页

绑定方式:

this.container.bind('min_threshold', this.load_previous_page.bind(this));
this.container.bind('max_threshold', this.load_next_page.bind(this));

使用示例

基本用法

var cols = new bricks.Cols({
  title: "Latest Articles",
  description: "A list of recent posts.",
  data_url: "/api/articles",
  data_params: { category: "tech" },
  page_rows: 10,
  cache_limit: 5,
  col_cwidth: "1fr",
  mobile_cols: 2,
  record_view: {
    type: "CardView",
    fields: ["title", "summary", "image"]
  }
});

cols.bind("record_click", function(data) {
  console.log("Selected:", data);
});

document.body.appendChild(cols.dom_element);

手动加载本地数据

cols.show_with_data({
  rows: [
    {id: 1, name: "Item 1"},
    {id: 2, name: "Item 2"}
  ]
});

注意事项

  1. 性能优化:只保留可视区域附近的页面,其他页面可手动卸载。
  2. 内存管理:长时间运行应用应注意 cache_limit 设置,避免内存泄漏。
  3. 事件绑定:确保 handle_click 使用 .bind(this, w) 正确绑定上下文。
  4. CSS 样式
    • .selected_record:用于标记选中项,请在 CSS 中定义高亮样式。
    • .filler:应用于 container,可能影响背景或间距。

注册信息

bricks.Factory.register('Cols', bricks.Cols);

可在模板中通过 <widget type="Cols" ...> 方式声明使用。


版本信息

  • 作者Bricks Framework Team
  • 最后更新:根据代码推断为现代异步 JS 架构ES6+
  • 兼容性:需支持 Promise、async/await、Custom Elements

相关组件

组件 作用
bricks.PageDataLoader 提供分页数据加载能力
bricks.VScrollPanel 提供滚动检测与阈值事件
bricks.DynamicColumn 实现响应式多列布局
bricks.widgetBuild 动态构建子组件的核心函数

文档完成度:完整覆盖功能、接口、流程与使用方式。
🔧 待修复问题show_with_data 方法中对 load_first_page 的调用缺少 this. 上下文。