You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Livewire与gridstack.js间同步任务数据,无需页面刷新

解决Livewire + Gridstack.js 新增/编辑任务无需刷新页面更新网格的问题

问题核心

由于网格区域使用了wire:ignore,Livewire不会自动重新渲染该部分DOM,因此新增或编辑任务后,必须手动调用Gridstack的API来更新网格内容,而非依赖Livewire的自动DOM更新机制。

解决步骤

  1. 修改事件传递逻辑,携带完整任务数据
    在task-create组件完成任务新增/编辑后,触发事件时需传递任务的完整信息,包括关联的项目ID和日期索引:

    // 在tasks.task-create组件的保存方法中添加
    $this->dispatch('taskAdjusted', [
        'task' => $task->toArray(),
        'project_id' => $task->project_id,
        'day_index' => $task->day_index // 对应网格的gs-x属性
    ]);
    
  2. 监听事件并调用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();
    });
    
  3. 优化网格实例存储,方便快速获取
    初始化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 20:43:21