AngularJS - 可拖动和多个连接的排序(jQuery UI + angular-common)
问题描述:
我试图扩展angular-common的出色dragdrop module,它可以处理连接到单个可排序对象的可拖动对象。 (原来如此线程落后角常见的的DragDrop模块为here)。AngularJS - 可拖动和多个连接的排序(jQuery UI + angular-common)
我设法连接两个sortables,和放拖动到他们每个人,以及sortables内重新安排工作的罚款(范围项目阵列得到更新预期)。事实上,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.');
});
}
};
}]);
控制器功能:
$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;
});
};
和视图:
<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>
任何帮助将不胜感激。
答
好吧,我终于解决了它。我创建了一个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();
}
});
}
});
}
};
}]);
在我添加了一个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;
});
}
}
};
和视图:
<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,据我所知,它没有任何实际功能。