如何在Livewire与gridstack.js间同步任务数据,无需页面刷新
解决Livewire + Gridstack.js 新增/编辑任务无需刷新页面更新网格的问题
问题核心
由于网格区域使用了wire:ignore,Livewire不会自动重新渲染该部分DOM,因此新增或编辑任务后,必须手动调用Gridstack的API来更新网格内容,而非依赖Livewire的自动DOM更新机制。
解决步骤
修改事件传递逻辑,携带完整任务数据
在task-create组件完成任务新增/编辑后,触发事件时需传递任务的完整信息,包括关联的项目ID和日期索引:// 在tasks.task-create组件的保存方法中添加 $this->dispatch('taskAdjusted', [ 'task' => $task->toArray(), 'project_id' => $task->project_id, 'day_index' => $task->day_index // 对应网格的gs-x属性 ]);监听事件并调用Gridstack API更新网格
调整taskAdjusted事件的监听逻辑,根据传递的数据判断是新增还是编辑任务,调用对应API操作网格:document.addEventListener('taskAdjusted', (event) => { const { task, project_id, day_index } = event.detail; // 根据项目ID找到对应的Gridstack实例 const grid = GridStack.closest(`#${project_id}`); if (!grid) return; // 处理编辑场景:更新已有任务 const existingItem = grid.getItem(`[gs-id="${task.id}"]`); if (existingItem) { // 更新网格项位置与宽度 grid.update(existingItem.el, { x: day_index, w: task.duration, y: 1 }); // 更新任务标题内容 existingItem.el.querySelector('.grid-stack-item-content span').textContent = task.title; return; } // 处理新增场景:创建并添加新网格项 const newItem = document.createElement('div'); newItem.className = 'grid-stack-item'; newItem.setAttribute('gs-id', task.id); newItem.setAttribute('gs-x', day_index); newItem.setAttribute('gs-w', task.duration); newItem.setAttribute('gs-y', 1); // 添加任务内容与Livewire交互事件 newItem.innerHTML = ` <div wire:click="$dispatchTo('tasks.task-create', 'editTask', { task_id: ${task.id} })" class="grid-stack-item-content"> <span>${task.title}</span> </div> `; // 将新项添加到网格 grid.addWidget(newItem); // 重新初始化Livewire动态DOM的交互事件 window.Livewire.restart(); });优化网格实例存储,方便快速获取
初始化Gridstack时将实例按项目ID存储,避免重复查找:let grids = {}; GridStack.initAll({ column: 6, cellHeight: '60px', cellWidth: '100px', float: false, resizable: { handles: 'e' }, margin: 2 }).forEach(grid => { grids[grid.el.id] = grid; // 按项目ID缓存网格实例 grid.on('change', function(event, items) { let newItems = []; items.forEach((el) => { newItems.push({_id: el._id, x: el.x, y: el.y, w: el.w, task_id: el.id}); }); $wire.taskMoved(newItems); }); }); // 后续可直接通过 grids[project_id] 获取对应网格实例
关键注意事项
- 必须通过Gridstack官方API(
addWidget/update)操作网格项,不能直接修改DOM,否则会破坏Gridstack内部状态。 - 动态创建的DOM元素需要调用
Livewire.restart()重新初始化交互事件,确保点击编辑功能正常。 - 事件传递必须携带
project_id和day_index,确保能精准定位到目标网格与位置。
内容的提问来源于stack exchange,提问作者dfeva
相关产品推荐
相关产品推荐

