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

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

问题:

我正在尝试从 jQuery 重新创建 Draggable + Sortable 功能,但无法将拖放的元素放入我的对象数组中。

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

<小时/>

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

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

<小时/>

我尝试过的:

我已经接近混合组合 ui-sortable$.draggable 指令包装器,但我的代码运行得不太好。

<小时/>

示例:

<小时/>

更新 1:

我在类似 ui-sortable 的指令与包装 $.draggable() 的指令相结合方面取得了进展,有点难看,但有效。

更新 2:

我现在可以使用它,但我从 jquery 获取索引并使用 PHP 将其切片到该位置,然后重新加载整个列表。谈论蹩脚肯定有更好的方法。

更新 3:

这是一个工作 example适合任何人的应用程序的模块化。

最佳答案

没有 Angular 魔法可以帮助您找到新元素或移动元素的位置,但使用 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();
            }
          })
        }
      } );
    }
  }
})

在 Controller 中,我创建项目数组并监听事件:

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

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

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

关于jquery - 将对象拖到可排序列表中 - AngularJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18835619/

相关文章:

javascript - jQuery(用户界面): Detect checking of a checkbox

使用英寸的 jquery ui slider

AngularJS 与 node-webkit

Javascript - 文件上传安全检查是否存在恶意软件、病毒

javascript - 使用 html5Mode 的 Angular 路由在重新加载后给出 'Not found' 页面

javascript - 将下拉选项列表样式设置为看起来像带有背景图像的按钮。 HTML/CSS

jquery - 将类添加到特定的 WordPress anchor 菜单

javascript - 使用 TinyMCE 进行实时预览(TinyMCE 的值(value))

javascript - 使用 jQuery、CSS 或两者来扩展 DIV 解决方案?

css - jQuery UI 风格的文本输入框