【问题标题】:Angular ui-sortable + angular-gridsterAngular ui-sortable + angular-gridster
【发布时间】:2026-01-16 08:05:03
【问题描述】:

我正在尝试结合ui-sortableangular-gridster 的功能,以便我可以从列表中拉出一个项目并将其放入可重新排列的网格中。 ui-sortable 和 angular-gridster 具有相同的 DOM 结构:

<div>
    <ul>
        <li ng-repeat="item in items"></li>
    </ul>
</div>

和属性允许它们附加到适当的 DOM 元素。我认为这将是一项非常简单的任务,但是我无法让他们一起工作。

我创建了这个CodePen,您可以在其中从 ui-sortable 的“Ingredents”列表拖到“My Coffee”列表中。拖入“我的咖啡”也会更新 angular-gridster“咖啡网格”,因为“我的咖啡”和“咖啡网格”使用相同的模型。我想做的就是直接从“Ingredients”拖到“Coffee Grid”中。

我看到的主要区别是,在设置之后,Gridster 的 DOM 看起来像这样:

<div gridster>
    **<div ng-transclude>**
        <ul>
           <li></li>
        </ul>
    </div>
</div>

而 ui-sortable 看起来像这样:

<div ui-sortable>
    <ul>
       <li></li>
    </ul>
 </div>

所以 angular-gridster 添加了一个&lt;div ng-trasclude&gt;,这让我认为 ui-sortable 可能无法附加到 DOM 元素,因为存在意外的 div。

我还在本地单步执行了 ui-sortable 源,并确定它的更新方法永远不会被调用。成功的拖放将调用以下方法:

start
activate x2
update
remove
receive
update
stop 

试图拖入 angular-gridster 看起来像这样:

start
activate x3
stop 

但是,我无法确定为什么从未调用更新并且没有引发错误。

我意识到这是一个非常具体的问题,我希望有人可能遇到过同样的问题,或者愿意帮助我进行一些调试。提前致谢!

【问题讨论】:

    标签: angularjs angularjs-scope angularjs-ng-repeat angular-ui angular-directive


    【解决方案1】:

    我通过使用以下扩展完成了您想要的:

    https://github.com/codef0rmer/angular-dragdrop

    我在 gridster ul 元素中添加了以下选项:

    <ul data-drop="true"
        data-jqyoui-options="{hoverClass: 'widgetDropOver'}"
        jqyoui-droppable="{onDrop:'widgetDropHandler'}"> 
           <li>...</li>
    </ul>
    

    我的元素无法排序,我只是这样使用它们:

    <a ng-click="widgetClickHandler()"
       data-drag="true"
       data-jqyoui-options="{revert: 'invalid'}"
       jqyoui-draggable="{animate:true, onDrag: 'widgetDragHandler', onStop: 'widgetDragStopHandler'}">
       element
    </a>
    

    以下是我用来跟踪拖动状态和 gridster 元素创建的函数:

    $scope.widgetDragHandler = function() {
      $scope.widgetDragged = true;
    };
    
    $scope.widgetDragStopHandler = function() {
      $scope.widgetDragged = false; 
    };
    
    $scope.widgetDropHandler = function(event, ui) {
       // we only need the drophandler to reset the widget dragged state,
       // ng-click is always fired, so we handle the widget adding there
       $scope.widgetDragged = false;
    };
    
    $scope.widgetClickHandler = function(type) {
      // only use the click handler when the user is not dragging
      if ($scope.widgetDragged === false) { 
        // create a gridster item here
        // I am using a ng-repeat to populate the gridster items
        // and so I only need to push a new item here to the list
      }
    }
    

    我使用 ng-click 是因为我希望通过简单的单击以及拖放操作将我的项目填充到 gridster。

    此外,要使其正常工作,您需要将以下内容添加到您的 css:

    .gridster>ul {
      height: 100%;
    }
    

    演示: http://jsfiddle.net/n7z3cykz/

    希望这能让你开始。

    【讨论】: