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

Blazor中使用gridstack.js跨面板拖拽组件失效如何解决?

问题:Blazor中gridstack.js外部组件无法拖拽到网格面板

我在Blazor应用里用gridstack.js实现了自定义仪表盘,网格内组件的拖拽缩放功能正常,但现在想从侧边面板拖拽组件到网格中,编写代码后能看到组件却无法拖动,求解决方法。

我的代码

HTML部分

<div class="col-lg-3">
    <div class="draggable-components-panel">
        <div class="draggable-component" id="dragComponent1">Drag Component 1</div>
        <div class="draggable-component" id="dragComponent2">Drag Component 2</div>
    </div>
</div>
<div class="col-lg-9">
    <div class="grid-stack">
        <div class="grid-stack-item" gs-w="4" gs-h="4" gs-x="0" gs-y="0" id="component1">
            <div class="nk-block-head-content"> 
                <h5 class="nk-block-title title">Overview</h5>
            </div>
            <div class="grid-stack-item-content">Component 1</div>
        </div>
        <div class="grid-stack-item" gs-w="6" gs-h="4" gs-x="6" gs-y="0" id="component2">
            <div class="grid-stack-item-content">Component 2</div>
        </div>                
    </div>
</div>

JS部分

export function loadData(layoutData) {           
    var data = JSON.parse(layoutData);
   
    data.forEach(item => {
        var element = document.getElementById(item.id);
        if (element) {
            element.setAttribute('gs-w', item.w);
            element.setAttribute('gs-h', item.h);
            element.setAttribute('gs-x', item.x);
            element.setAttribute('gs-y', item.y);
            console.log(`Updated ${item.id} with width: ${item.w}, height: ${item.h}`);
        }
    });

    // Reinitialize GridStack after updating the elements
    GridStack.init();
}

export function InitGrid() {
    $(document).ready(function () {
        const grid = GridStack.init();

        // Make the grid items draggable and resizable
        $('.grid-stack').gridstack({
            draggable: {
                handle: '.grid-stack-item-content'
            }
        });

        // Initialize draggable components
        $('.draggable-component').draggable({
            revert: "invalid",
            helper: "clone",
            start: function (event, ui) {
                $(ui.helper).addClass("grid-stack-item");
            }
        });

        // Initialize the droppable area (GridStack)
        $('.grid-stack').droppable({
            accept: '.draggable-component',
            drop: function (event, ui) {
                const item = $(ui.helper).clone();
                const grid = GridStack.init();
                const node = {
                    x: 0,
                    y: 0,
                    width: 2,
                    height: 2
                };
                grid.addWidget(item, node);
            }
        });
    });
}
解决方案

你的代码存在几个关键问题,导致外部组件无法拖拽,以下是针对性修复:

1. 消除GridStack重复初始化

  • 代码中先后调用GridStack.init()和$('.grid-stack').gridstack(),重复初始化会导致网格实例混乱。
  • 修复:只保留一次初始化,存储网格实例供后续使用:
    const grid = GridStack.init({
        draggable: {
            handle: '.grid-stack-item-content'
        }
    });
    

2. 确保依赖脚本正确引入

  • 外部组件拖拽依赖jQuery和jQuery UI的draggable模块,Blazor项目需在_Host.cshtml(Server)或index.html(WebAssembly)中引入:
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gridstack@8.2.0/dist/gridstack.min.js"></script>
    

3. 修正拖拽组件的DOM结构

  • GridStack组件必须包含grid-stack-item-content子元素,否则无法被正确识别。修改外部组件HTML:
    <div class="draggable-component" id="dragComponent1">
        <div class="grid-stack-item-content">Drag Component 1</div>
    </div>
    <div class="draggable-component" id="dragComponent2">
        <div class="grid-stack-item-content">Drag Component 2</div>
    </div>
    

4. 修复Drop事件中的实例重复创建

  • Drop事件中再次调用GridStack.init()会重建网格实例,导致无法添加组件,应使用已存储的网格实例。

完整修复后的JS代码

export function loadData(layoutData) {           
    var data = JSON.parse(layoutData);
   
    data.forEach(item => {
        var element = document.getElementById(item.id);
        if (element) {
            element.setAttribute('gs-w', item.w);
            element.setAttribute('gs-h', item.h);
            element.setAttribute('gs-x', item.x);
            element.setAttribute('gs-y', item.y);
            console.log(`Updated ${item.id} with width: ${item.w}, height: ${item.h}`);
        }
    });

    // 重新初始化前销毁旧实例
    GridStack.destroyAll();
    GridStack.init();
}

export function InitGrid() {
    $(document).ready(function () {
        // 仅初始化一次网格,保存实例
        const grid = GridStack.init({
            draggable: {
                handle: '.grid-stack-item-content'
            }
        });

        // 配置外部组件拖拽
        $('.draggable-component').draggable({
            revert: "invalid",
            helper: "clone",
            appendTo: 'body',
            start: function (event, ui) {
                $(ui.helper).addClass("grid-stack-item").css({width: 'auto', height: 'auto'});
            }
        });

        // 配置网格为可放置区域
        $('.grid-stack').droppable({
            accept: '.draggable-component',
            drop: function (event, ui) {
                const componentText = ui.draggable.text();
                // 创建符合GridStack要求的组件结构
                const item = $(`
                    <div class="grid-stack-item">
                        <div class="grid-stack-item-content">${componentText}</div>
                    </div>
                `);
                // 使用已有的网格实例添加组件
                grid.addWidget(item, {
                    x: 0,
                    y: 0,
                    width: 2,
                    height: 2
                });
            }
        });
    });
}

内容的提问来源于stack exchange,提问作者Isuru

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 20:14:51