将对象拖到可排序列表中 – AngularJS

问题:

我正在尝试从jQuery重新创建Draggable + Sortablefunction,并且无法将被删除的元素放入我的对象数组中。

我想将$ .draggable()按钮拖到$ .sortable()列表中。我希望按钮代表具有属性的对象(可以是关联数组,或对象本身),当我将其放入列表中时我希望它将自己放入数组中的位置。


需要明确的是:我在左侧的菜单中有一系列潜在的对象。 在右边,我使用$ http来调用我的API来检索一个包含所有字段都在$ scope中的表单。 我希望将该潜在对象(如textarea)放入该表单的删除位置的字段中。

jquery位很简单,但是$ scope数组中不存在的对象是问题所在。


我尝试过的:

我很接近混合使用ui-sortable和$ .draggable指令包装器,但是我的代码运行得不好。


例子:

  • KnockoutJS示例: http : //bit.ly/15yrf8X
  • jQuery演示: http : //jqueryui.com/draggable/#sortable

更新1:

我已经取得了进展,使用ui-sortable like指令结合包装$ .draggable()的指令,有点难看但有效。

更新2:

我现在有它工作,但我从jquery获取索引并使用php将其切片到该位置,然后重新加载整个列表。 谈论跛脚必须有更好的方法。

更新3:

这是一个模块化的工作示例,适用于任何人的应用程序。

http://clouddueling.github.io/angular-common

没有角度魔法可以帮助你找到新元素或移动元素的位置,但是使用jQuery很容易。 我已经在指令中创建了一个jQueryUI-demo包装可排序和可拖动的示例:

http://plnkr.co/edit/aSOlqR0UwBOXgpQSFKOH?p=preview

  • Drag me down
  • {{item.name}}

my-draggable是相应的my-sortable -element的id。 我的拖延是非常直截了当的:

 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}); }) 

如您所见,当您添加或移动元素时,范围中的模型会更新。

这些指令不是很通用 – 您可能需要进行一些调整才能使它们与您的应用程序一起使用。

您应该能够在链接function中执行所需的所有操作。

 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); } } })