jquery - AngularJS - 可拖动和多个连接的可排序(jQuery UI + Angular-Common)

标签 jquery angularjs jquery-ui jquery-ui-sortable

我正在尝试扩展 angular-common非常好dragdrop module它可以处理连接到单个可排序的可拖动对象。 (Angular-common 的拖放模块背后的原始 SO 线程是 here 。)

我设法连接两个可排序对象,并将一个可拖动对象拖放到每个可排序对象上,然后在可排序对象内重新排列工作正常(范围项目数组按预期更新)。事实上,UI 部分工作正常,但当我将列表项从一个可排序项拖到另一个可排序项时,我似乎无法弄清楚如何更新 Angular 范围中的项数组。

工厂:

.factory('DragDropHandler', [function() {
    return {
        dragObject: undefined,
        addObject: function(object, objects, to) {
            objects.splice(to, 0, object);
        },
        moveObject: function(objects, from, to) {
            objects.splice(to, 0, objects.splice(from, 1)[0]);
        }
    };
}])

可删除(可排序)指令:

.directive('droppable', ['DragDropHandler', function(DragDropHandler) {
    return {
        scope: {
            droppable: '=',
            ngUpdate: '&',
            ngCreate: '&'
        },
        link: function(scope, element, attrs){
            element.sortable({
              connectWith: ['.draggable','.sortable'],
            });
            element.disableSelection();
            var list = element.attr('id');
            element.on("sortdeactivate", function(event, ui) {

                var from = angular.element(ui.item).scope().$index;
                var to = element.children().index(ui.item);

                //console.log('from: ' + from + ', to: ' +to);

                if (to >= 0 ){
                    scope.$apply(function(){
                        if (from >= 0) {
                            DragDropHandler.moveObject(scope.droppable, from, to, list);
                            scope.ngUpdate({
                                from: from,
                                to: to,
                                list: list
                            });
                        } else {

                            scope.ngCreate({
                                object: DragDropHandler.dragObject,
                                to: to,
                                list: list
                            });

                            ui.item.remove();
                        }
                    });
                }
            });

            element.on("sortremove", function(event, ui) {
              //console.log(element);
              //console.log('a sort item is removed from a connected list and is dragged into another.');
            });
            element.on("sortreceive", function(event, ui) {
              //console.log(element);
              //console.log('item from a connected sortable list has been dropped.');
            });
        }
    };
}]);

Controller 功能:

$scope.updateObjects = function(from, to, list) {
    var itemIds = _.pluck($scope.items[list], 'id');
    //console.log(itemIds);
};

$scope.createObject = function(object, to, list) {
    console.log(list);
    console.log($scope.items[list]);
    var newItem = angular.copy(object);
    newItem.id = Math.ceil(Math.random() * 1000);
    DragDropHandler.addObject(newItem, $scope.items[list], to);
};

$scope.deleteItem = function(itemId) {
    $scope.items = _.reject($scope.items, function(item) {
        return item.id == itemId; 
    });
};

以及 View :

<h3>sortable</h3>
<ul
    droppable='items.list1'
    ng-update='updateObjects(from, to)'
    ng-create='createObject(object, to, list)'
    id="list1" class="sortable">
    <li
        class="ui-state-default"
        ng-repeat="item in items.list1 track by item.id">
        {{ $index }}: {{ item.id }} - {{ item.name }}
        <button
            ng-click='deleteItem(item.id)'
            class='btn btn-xs pull-right btn-danger'>X</button>
    </li>
</ul>
<h3>sortable</h3>
<ul
    droppable='items.list2'
    ng-update='updateObjects(from, to)'
    ng-create='createObject(object, to, list)'
    id="list2" class="sortable">
    <li
        class="ui-state-default"
        ng-repeat="item in items.list2 track by item.id">
        {{ $index }}: {{ item.id }} - {{ item.name }}
        <button
            ng-click='deleteItem(item.id)'
            class='btn btn-xs pull-right btn-danger'>X</button>
    </li>
</ul>

Working example on Plunker.

任何帮助将不胜感激。

最佳答案

好吧,我终于解决了。我创建了一个fork on GitHub PLUNKER UPDATED!

说明:关键是检查另一个可排序列表是否为拖动的对象设置了 ui.sender。如果已设置,则该对象来自另一个可排序对象,否则不是。

扩展的可删除(可排序)指令:

.directive('droppable', ['DragDropHandler', function(DragDropHandler) {
    return {
        scope: {
            droppable: '=',
            ngMove: '&',
            ngCreate: '&'
        },
        link: function(scope, element, attrs){
            element.sortable({
              connectWith: ['.draggable','.sortable'],
            });
            element.disableSelection();
            var list = element.attr('id');
            element.on("sortupdate", function(event, ui) {

                var from = angular.element(ui.item).scope().$index;
                var to = element.children().index(ui.item);

                if (to >= 0 ){
                  //item is moved to this list
                    scope.$apply(function(){
                        if (from >= 0) {
                          //item is coming from a sortable

                          if (!ui.sender) {
                            //item is coming from this sortable
                              DragDropHandler.moveObject(scope.droppable, from, to);

                          } else {
                            //item is coming from another sortable
                            scope.ngMove({
                                from: from,
                                to: to,
                                fromList: ui.sender.attr('id'),
                                toList: list
                            });
                            ui.item.remove();
                          }
                        } else {
                          //item is coming from a draggable
                            scope.ngCreate({
                                object: DragDropHandler.dragObject,
                                to: to,
                                list: list
                            });

                            ui.item.remove();
                        }
                    });
                }
            });

        }
    };
}]);

在 Controller 中,我添加了一个 moveObject 函数,负责将对象从旧数组移动到新数组:

$scope.moveObject = function(from, to, fromList, toList) {
    var item = $scope.items[fromList][from];
    DragDropHandler.addObject(item, $scope.items[toList], to);
    $scope.items[fromList].splice(0, 1);
}

并且必须更新deleteItem函数以处理多个可排序的多个数组(只是为了保持演示完全正常工作):

$scope.deleteItem = function(itemId) {
  for (var list in $scope.items) {
    if ($scope.items.hasOwnProperty(list)) {
      $scope.items[list] = _.reject($scope.items[list], function(item) {
        return item.id == itemId; 
      });
    }
  }
};

以及 View :

<h3>sortable</h3>
<ul
    droppable='items.list2'
    ng-move='moveObject(from, to, fromList, toList)'
    ng-create='createObject(object, to, list)'
    id="list2" class="sortable">
    <li
        class="ui-state-default"
        ng-repeat="item in items.list2 track by item.id">
        {{ $index }}: {{ item.id }} - {{ item.name }}
        <button
            ng-click='deleteItem(item.id)'
            class='btn btn-xs pull-right btn-danger'>X</button>
    </li>
</ul>

我删除了 ngUpdate,据我所知,它没有任何实际功能。

关于jquery - AngularJS - 可拖动和多个连接的可排序(jQuery UI + Angular-Common),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26311111/

相关文章:

javascript - 禁用对 UI-Grid 中特定列的过滤

javascript - Angular.js 和 Node.js 在页面加载时调用 Node

angularjs - 在 Angular 指令中查找元素子元素

css - jQuery UI 在 Bootstrap 之前加载,但仍然覆盖 Bootstrap 样式?

jquery - 在我刷新页面之前将新项目移至新添加的列表时出现问题

javascript - 如何让JQuery json函数在javascript之前运行

javascript - jScript 确认当字段脏时导航离开,多浏览器实现?

javascript - if 语句的第二部分不起作用

JQUERY UI - 根据验证选择选项卡

javascript - 检查元素状态是否从隐藏变为可见