拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

gridstack.js Angular 集成:GridstackItemComponent 网格项组件完全指南

gridstack.js Angular 集成:GridstackItemComponent 网格项组件完全指南 前端UI组件【免费下载链接】gridstack.jsBuild interactive dashboards in minutes.项目地址https://gitcode.com/gh_mirrors/gr/gridstack.js点击查看免费下载本文以 angular/doc/api/gridstack-item.component.md 为骨架结合 gridstack-item.component.ts 源码与 Angular 演示项目 展开。读者将掌握如何使用gridstack-item声明单个网格项、通过options输入配置位置/尺寸/行为、理解动态创建与序列化的底层机制以及如何配合GridstackComponent构建完整的 Angular 仪表盘。一、GridstackItemComponent 是什么GridstackItemComponent是 gridstack.js 为 Angular 提供的单个网格项grid item组件包装器以gridstack-item为选择器定义于 angular/projects/lib/src/lib/gridstack-item.component.ts:56。它代表网格中的一块独立区域负责四件事动态内容的创建与管理通过ViewContainerRef动态挂载子组件与父级GridstackComponent的集成由父组件统一调度创建/更新/删除组件生命周期与清理实现OnDestroy销毁时释放引用Widget 选项与配置通过options输入控制位置、尺寸与行为组件声明为standalone: true见源码 gridstack-item.component.ts:53因此推荐直接作为独立组件导入而非依赖已废弃的GridstackModule见 gridstack.module.ts 中标注的deprecated。模板结构div classgrid-stack-item-content !-- 动态创建的子组件渲染于此推荐方式 -- ng-template #container/ng-template !-- 静态写在 DOM 中的内容不推荐 -- ng-content/ng-content !-- 使用 GridStackWidget.content 时的兜底 HTML 内容 -- {{options.content}} /div三个区域对应三种内容承载方式动态组件、模板静态内容、content字符串兜底。源码注释明确给出了推荐顺序优先使用动态组件方式。二、最小用法在父网格中声明一个网格项文档给出的最简示例gridstack gridstack-item [options]{x: 0, y: 0, w: 2, h: 1} my-widget-component/my-widget-component /gridstack-item /gridstack其中gridstack是父级GridstackComponent选择器定义于 gridstack.component.ts:70。gridstack-item必须作为父网格的子元素使用[options]传入描述该网格项位置与尺寸的GridStackNode对象。演示项目 app.component.html:27-29 展示了两种静态声明方式gridstack [options]gridOptions (changeCB)onChange($event) gridstack-item gs-x1 gs-y0item 1/gridstack-item gridstack-item gs-x3 gs-y0 gs-w2item 2 wide/gridstack-item /gridstack注意直接在 DOM 模板中声明网格项属于template 方式源码 gridstack.component.ts:89-93 的注释明确标注为not recommended approach推荐改用动态创建见下文第五节。结合 ngFor 批量渲染演示项目 app.component.html:39 展示了配合*ngFor的使用方式并通过trackBy提供稳定的节点 idgridstack [options]gridOptions gridstack-item *ngForlet n of items; trackBy: identify [options]n/gridstack-item /gridstack对应的identify方法见 app.component.ts:244-246按w.id匹配保证 Angular 能正确识别增删改的项。需要修改某个网格项时应直接重新设置其options如gridItem.options {w: 3}而不是改数组元素后期望 ngFor 自动同步见 app.component.ts:216-220 的modifyNgFor()注释说明。三、options 输入配置单个网格项Setter 行为源码级解析options是Input()属性类型为GridStackNode。其 setter 逻辑gridstack-item.component.ts:89-98分为两种情况Input() public set options(val: GridStackNode) { const grid this.el.gridstackNode?.grid; if (grid) { // 网格已构建走更新路径 grid.update(this.el, val); } else { // 网格未构建暂存到 _options并把自定义元素 el 一并写入 // 保证后续 GridStack 复用它而不是重新创建通用 div this._options {...val, el: this.el}; } }网格已初始化时el.gridstackNode?.grid存在调用底层grid.update(this.el, val)就地更新该网格项网格尚未初始化时将选项展开存入_options并附带el: this.el—— 这是实现复用组件自身 DOM 元素的关键细节避免 GridStack 内部再生成一个普通div来承载内容。Getter 行为public get options(): GridStackNode { return this.el.gridstackNode || this._options || {el: this.el}; }返回最新的网格选项优先取 GridStack 构建后挂在元素上的gridstackNode实时反映拖拽/缩放后的坐标否则回退到初始的_options最后兜底为仅含el的空对象。文档示例位置、尺寸与行为文档给出的完整配置示例itemOptions: GridStackNode { x: 0, y: 0, w: 2, h: 1, noResize: true, content: Item content };其中x/y为列/行坐标w/h为占用的列数/行数noResize禁止用户缩放content为网格项内的 HTML 内容。GridStackWidget 支持的全部节点级选项从核心类型定义 src/types.ts:466-498 可以看到GridStackWidgetGridStackNode的基础接口支持以下与GridstackItemComponent直接相关的配置项选项类型说明默认值x/ynumber网格项起始列/行坐标w/hnumber占用的列宽/行高autoPositionboolean为true时忽略x, y自动放到第一个可用位置默认falseminW/maxWnumber缩放/创建时允许的最小/最大宽度默认无约束minH/maxHnumber缩放/创建时允许的最小/最大高度默认无约束noResizeboolean禁止用户直接缩放默认无约束noMoveboolean禁止用户直接移动默认无约束lockedboolean禁止被其他网格项或 API 推挤与noMove仅限制用户操作不同idstring写入gs-id属性的值contentstring作为网格项内部 HTML 追加的内容lazyLoadboolean滚动到可见区域时才创建内容sizeToContentboolean \| number根据内容自适应高度可设上限值subGridOptsGridStackOptions嵌套子网格的选项与子项列表在实际项目中动态网格项的典型写法见 app.component.ts:41public sub0: NgGridStackWidget[] [ {x: 0, y: 0, component: app-a}, {x: 1, y: 0, component: app-a, props: {text: bar}}, {x: 1, y: 1, content: plain html}, {x: 0, y: 1, component: app-b} ];四、el 访问器与 GridItemCompHTMLElement 接口el 访问器public get el(): GridItemCompHTMLElement { return this.elementRef.nativeElement; }返回该组件对应的原生 DOM 元素。由于类型被扩展为GridItemCompHTMLElement该元素上不仅挂有 GridStack 的网格字段如gridstackNode还保存了组件自身引用。GridItemCompHTMLElement 接口文档中单独定义了该接口gridstack-item.component.ts:14-17export interface GridItemCompHTMLElement extends GridItemHTMLElement { /** 指向 Angular GridstackItemComponent 的反向引用 */ _gridItemComp?: GridstackItemComponent; }它继承自GridItemHTMLElementGridStack 底层为网格项元素附加的字段集合并额外声明_gridItemComp属性。这个反向引用是 Angular 集成的基础GridStack 引擎只操作原生 DOM而引擎需要回调 Angular 组件时就通过(n.el as GridItemCompHTMLElement)?._gridItemComp找到对应组件实例。_gridItemComp在构造函数中建立constructor(protected readonly elementRef: ElementRefGridItemCompHTMLElement) { this.el._gridItemComp this; }并在ngOnDestroy()中删除public ngOnDestroy(): void { this.clearOptions(); delete this.childWidget; delete this.el._gridItemComp; delete this.container; delete this.ref; }el属性的典型用途父组件在updateAll()gridstack.component.ts:295-303中收集模板网格项的options、clearOptions()后统一grid.load(layout)做增量差异更新。五、三个关键属性container / ref / childWidgetcontainer动态组件挂载点ViewChild(container, { read: ViewContainerRef, static: true }) public container?: ViewContainerRef;对应模板中的ng-template #container是在网格项内部以编程方式创建子组件的容器。动态创建链路如下见 gridstack.component.ts:350-420 的gsCreateNgComponents父网格的GridstackComponent在constructor中把gsCreateNgComponents注册为GridStack.addRemoveCBgridstack.component.ts:250-258当 GridStack 引擎需要新增一个网格项时调用gridComp?.container?.createComponent(GridstackItemComponent)动态创建gridstack-item依据节点上的component键从componentMap查表找到真实组件类型后通过gridItem.container?.createComponent(type)挂载到网格项内部若子组件继承自BaseWidget有serialize/deserialize方法则存入gridItem.childWidget并调用deserialize(n)注入数据gridstack.component.ts:387-395。ref动态实例的释放句柄public ref: ComponentRefGridstackItemComponent | undefined;当组件是动态创建而非模板静态声明时保存创建它的ComponentRef。删除网格项时引擎通过_gridItemComp找到组件优先调用gridItem.ref.destroy()正确触发 Angular 销毁流程否则回退调用gridItem.ngOnDestroy()见 gridstack.component.ts:430-434。childWidget序列化与状态恢复的桥梁public childWidget: BaseWidget | undefined;指向网格项内继承BaseWidget的子组件。它的作用是配合BaseWidget的serialize()/deserialize()完成额外数据的存取保存时gsSaveAdditionalNgInfogridstack.component.ts:445-459调用gridItem.childWidget?.serialize()把返回的props写入保存的 widget JSON恢复时gsUpdateNgComponentsgridstack.component.ts:464-467在网格项更新时调用childWidget.deserialize(w)同步数据。BaseWidgetbase-widget.ts是自定义组件的推荐基类其deserialize()默认实现会利用ComponentRef.setInput()正确回填Input()字段与 Angular 17 的 signal input见 base-widget.ts:93-107。六、方法clearOptions() 与 ngOnDestroy()clearOptions()public clearOptions(): void { delete this._options; }文档描述为clears the initial options now that weve built。当 GridStack 引擎接管网格项后_options中的初始配置已同步到元素的gridstackNode此时删除_options可避免内存残留。父组件updateAll()会在收集完每个网格项的options后立即调用它gridstack.component.ts:298-301防止重复构建时使用过期数据。ngOnDestroy()public ngOnDestroy(): void { ... }实现OnDestroy接口在组件销毁前执行清理删除_options、childWidget、_gridItemComp反向引用、container与ref切断组件与 DOM、父网格及子组件之间的引用链避免内存泄漏。演示项目中的 Leak Test 案例app.component.html:106-114专门用于验证load()与clear()循环操作下无内存泄漏。七、与父组件 GridstackComponent 的协作关系GridstackItemComponent不能独立工作必须与父级GridstackComponent配合。整体协作机制可概括为注册GridstackComponent.registerComponents([MyWidget])将组件按 selector 注册进componentMapgridstack.component.ts:230-232创建GridStack 引擎触发addRemoveCB即gsCreateNgComponents动态创建gridstack-item并挂载子组件使用BaseWidget.deserialize()注入props运行用户拖拽/缩放改变坐标实时反映在el.gridstackNode上optionsgetter 因此总能返回最新状态序列化grid.save()时通过gsSaveAdditionalNgInfo调用childWidget.serialize()收集组件自定义数据写入props销毁引擎触发移除时调用ComponentRef.destroy()或ngOnDestroy()完成清理。子组件定义示例文档与 base-widget.ts 中的标准写法Component({ selector: app-my-widget, template: div{{data()}}/div, standalone: true, }) export class MyWidget extends BaseWidget { data input(); // Angular 17 signal input也可用 Input() data override serialize() { return { data: this.data() }; } } // 注册后widget JSON 中的 { component: app-my-widget, props: { data: hello } } 即可自动实例化 GridstackComponent.registerComponents([MyWidget]);Angular 扩展类型见 types.tsNgGridStackWidget在GridStackWidget基础上增加component组件查找键默认即Component.selector、props序列化数据与subGridOpts嵌套子网格三个字段。八、运行演示项目仓库自带的 Angular 演示应用angular/projects/demo提供了 10 个场景覆盖本文涉及的全部能力Component template模板静态声明gridstack-itemshow3Component ngForngFor trackBy批量渲染与增删show4Component Dynamic动态创建、跨网格拖拽、Save/Clear/Loadshow5Nested Grid嵌套子网格show6Two Grids sidebar多网格与侧边栏创建组件show7Lazy Load滚动到可视区域才创建组件show8Leak Test反复 load/clear 验证内存释放show9。在angular/目录下执行npm install后运行npm start即可查看这些示例实际调用关系与交互行为可直接对照 app.component.ts 验证。九、小结GridstackItemComponent是 gridstack.js Angular 集成中一砖一瓦的单元它向上对接GridstackComponent的统一调度向下通过container/childWidget承载动态组件与序列化数据用_gridItemComp反向引用打通原生 DOM 引擎与 Angular 组件生命周期。理解其options输入的分支逻辑构建前暂存 / 构建后grid.update、el上的反向引用以及BaseWidget序列化链路是驾驭动态仪表盘开发的关键。赞分享前端UI组件【免费下载链接】gridstack.jsBuild interactive dashboards in minutes.项目地址https://gitcode.com/gh_mirrors/gr/gridstack.js点击查看免费下载相关推荐PrimeNG InputNumber 组件完全指南数字输入、货币格式化与 Angular 表单集成PrimeNG InputNumber 组件完全指南数字输入、货币格式化与 Angular 表单集成 InputNumber 是 PrimeNG 提供的数值输前端UI组件eCapture ecaptureq 详解用 WebSocket Protobuf 实时流式接收 eBPF 捕获事件与运行日志eCapture ecaptureq 详解用 WebSocket Protobuf 实时流式接收 eBPF 捕获事件与运行日志 eCapture旁观者前端UI组件daisyUI 与 Angular为 Angular 项目引入 Tailwind CSS 组件库的完整集成指南daisyUI 与 Angular为 Angular 项目引入 Tailwind CSS 组件库的完整集成指南 摘要本文面向 Angular 开发者讲解如前端UI组件上一篇深入解析xv6-riscv内核栈设计kstack与用户栈隔离机制终极指南下一篇Front-End Checklist 无障碍轮播Carousel实战指南从 ARIA 标记到键盘导航与动效偏好处理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表