我试图从jQuery重新创建Draggable + Sortable功能,并且无法将被删除的元素放入我的对象数组中。
我想将$.draggable()
按钮拖到$.sortable()
列表中。我希望按钮能够表示具有属性的对象(可以是关联数组,也可以是对象本身),当我将其放入列表中时,我希望它将自己放入数组中的位置。
为了清楚起见,我在左侧菜单中有一系列潜在对象。在右侧,我使用$http
调用我的API来检索包含所有字段$scope
的表单。我希望将该潜在对象(如textarea
)放入丢弃位置的那个表单字段中。
jquery位很简单但是$scope
数组中不存在的对象是问题所在。
我在混合使用ui-sortable
和$.draggable
指令包装器时非常接近,但我的代码运行得不好。
我已经在ui-sortable
喜欢的指令和一个包装$.draggable()
的指令中取得了进展,有点难看但有效。
我现在正在使用它但我从jquery获取索引并使用PHP将其切片到该位置然后重新加载整个列表。谈论跛脚必须有更好的方法。
这是适用于任何人应用的模块化工作example。
答案 0 :(得分:17)
没有角度魔法可以帮助你找到新元素或移动元素的位置,但是使用jQuery很容易。我已经在指令中创建了一个jQueryUI-demo包装可排序和可拖动的示例:
http://plnkr.co/edit/aSOlqR0UwBOXgpQSFKOH?p=preview
<ul>
<li my-draggable="#sortable" class="ui-state-highlight">Drag me down</li>
</ul>
<ul my-sortable id="sortable">
<li class="ui-state-default" ng-repeat="item in items">{{item.name}}</li>
</ul>
我的my-draggable
的值是相应my-sortable
- 元素的ID。 my-draggable非常直接:
app.directive('myDraggable',function(){
return {
link:function(scope,el,attrs){
el.draggable({
connectToSortable: attrs.myDraggable,
helper: "clone",
revert: "invalid"
});
el.disableSelection();
}
}
})
在my-sortable
中,我收听deactivate
事件,该事件表明某个元素已被删除。 from
是数组中元素的位置,它是ng-repeat的来源。 ng-repeat为每个元素创建一个子范围,其中$ index变量指示当前元素在数组中的位置。如果$ index未定义,我知道它是一个新元素(可能是一个更好的方法来确定它,但它适用于这个例子)。 to
是该项目的新位置。如果移动现有元素,我会发出'my-sorted'事件,如果添加了新项目,我会发出'my-created'事件。
app.directive('mySortable',function(){
return {
link:function(scope,el,attrs){
el.sortable({
revert: true
});
el.disableSelection();
el.on( "sortdeactivate", function( event, ui ) {
var from = angular.element(ui.item).scope().$index;
var to = el.children().index(ui.item);
if(to>=0){
scope.$apply(function(){
if(from>=0){
scope.$emit('my-sorted', {from:from,to:to});
}else{
scope.$emit('my-created', {to:to, name:ui.item.text()});
ui.item.remove();
}
})
}
} );
}
}
})
在控制器中,我创建items-array并收听事件:
$scope.items = [
{name:'Item 1'},
{name:'Item 2'},
{name:'Item 3'},
{name:'Item 4'},
];
$scope.$on('my-sorted',function(ev,val){
// rearrange $scope.items
$scope.items.splice(val.to, 0, $scope.items.splice(val.from, 1)[0]);
})
$scope.$on('my-created',function(ev,val){
// create new item at position
$scope.items.splice(val.to, 0,
{name:'#'+($scope.items.length+1)+': '+val.name});
})
如您所见,当您添加或移动元素时,范围中的模型会更新。
这些指令不是很通用 - 您可能需要进行一些调整才能使它们与您的应用程序一起使用。
答案 1 :(得分:1)
您应该能够在链接功能中完成所需的一切。
myapp.directive("menuDrag", function () {
return{
restrict: "A",
link: function (scope, element, attrs) {
var item = $(".draggable").draggable(
{
snap: true,
revert: false,
// scope:".dropable"
//scope: "tasks"
}
)
var target = $(".dropable").droppable({
greedy: true,
hoverClass: "warning",
accept: ".draggable"
})
item.on("drag", function (evt) {
item.css = ('background-color', 'red');
//evt.stopPropagation();
//evt.preventDefault();
})
target.on("over", function (evt) {
target.css('background-color', 'blue')
return false;
});
target.on("out", function (evt) {
dropBox.css('background_color', 'red');
return false;
});
target.on("drop", function (evt) {
alert("Droped");
return false;
});
//dragEnterLeave(evt);
}
}
})