angular dragdrop(使用jQuery UI) - 禁用交换

时间:2016-01-27 22:16:28

标签: angularjs jquery-ui drag-and-drop jquery-ui-draggable jquery-ui-droppable

我在交换拖放的元素时遇到问题。

DOM / Angular结构:



angular.module('app', ['ngDragDrop'])
.controller('controller', function($scope) {
  $scope.listItems = [
    {name: "some name", title: "title"},
    {name: "some name2", title: "title2"},
  ];
  $scope.input = {};
  $scope.draggableOprions = {
    revert: 'invalid'
  }
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script src="https://code.angularjs.org/1.4.9/angular.js"></script>
<script src="https://cdn.jsdelivr.net/angular.dragdrop/1.07/angular-dragdrop.min.js"></script>
<div ng-app="app">
  <div ng-controller="controller">
    <div class="container">
      <ul>
        <li data-drag="true" 
        data-jqyoui-options="draggableOprions" 
        jqyoui-draggable="{animate:true}" 
        ng-model="item" ng-repeat="item in listItems track by $index">
          {{item.title}}
        </li>
      </ul>
    </div>

    <div class="container" 
    data-drop="true" 
    data-jqyoui-options jqyoui-droppable 
    ng-model="input">
      <input ng-model="input.name">
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

问题:

当我拖放list item 1时,name的{​​{1}}属性会转到list item 1模型。但input中不再提供此功能。实际上,list item 1将其放入list item 1undefined || null值为input。如果我现在尝试在list item 2中拖放input项,则值交换(list item 1 = undefined || null ?list item 2 = list item 1 value以及input模型等于列表项2值。所以一切都洗了。

我需要什么: 我需要在输入中拖放列表项,避免丢失列表项中的值。每次我在输入中删除列表项时,我都需要它的值来绑定到输入。

开箱即用
我可以更改拖放库,甚至使用源代码,但库是更好的选择。我接受几乎所有没有破坏任何良好代码标准的好工作答案(我的意思是我需要的代码不会破坏其他代码并具有良好的结构)。

2 个答案:

答案 0 :(得分:2)

我建议使用 ngDraggable ,一个与jQuery或jQuery-ui无依赖关系的Angular模块。

以下是工作代码段或检查我的Codepen

&#13;
&#13;
angular.module('app', ['ngDraggable'])
  .controller('controller', function($scope) {

    $scope.listItems = [{
      name: "some name",
      title: "title1"
    }, {
      name: "some name2",
      title: "title2"
    }, {
      name: "some name3",
      title: "title3"
    }, ];

    $scope.droppedObjects = [];
    $scope.input = {};
  
    // drag complete over drop area
    $scope.onDragComplete = function(data, evt) {
      console.log("drag success, data:", data);
      var index = $scope.droppedObjects.indexOf(data);
      if (index > -1) {
        $scope.droppedObjects.splice(index, 1);
      }
    }
    
    // drop complete over drop area
    $scope.onDropComplete = function(data, evt) {
      console.log("drop success, data:", data);
      var index = $scope.droppedObjects.indexOf(data);
      if (index == -1)
        $scope.droppedObjects.push(data);
    }
    
    // drop complete over input box
    $scope.onDropCompleteInput = function(data, evt) {
      console.log("drop on input success, data:", data);
      $scope.input = data;
    }
    
    // drop complete over items area (remove from dropped list)
    $scope.onDropCompleteRemove = function(data, evt) {
      console.log("drop success - remove, data:", data);
      var index = $scope.droppedObjects.indexOf(data);
      if (index != -1)
        $scope.droppedObjects.splice(index);
    }
    
    // other draggable events handlers

    var onDraggableEvent = function(evt, data) {
      console.log("128", "onDraggableEvent", evt, data);
    }
    $scope.$on('draggable:start', onDraggableEvent);
    //$scope.$on('draggable:move', onDraggableEvent);
    $scope.$on('draggable:end', onDraggableEvent);
  
  });
&#13;
* {
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

[ng-drag] {
  -moz-user-select: -moz-none;
  -khtml-user-select: none;
  -webkit-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.item {
  width: 100px;
  height: 60px;
  background: rgba(255, 0, 0, 0.5);
  color: white;
  text-align: center;
  padding-top: 5%;
  display: inline-block;
  margin: 0 10px;
  cursor: move;
}

ul.draggable-objects:after {
  display: block;
  content: "";
  clear: both;
}

.draggable-objects li {
  float: left;
  display: block;
  width: 120px;
  height: 100px;
}

[ng-drag].drag-over {
  border: solid 1px red;
}

[ng-drag].dragging {
  opacity: 0.5;
}

.drop-container {
  background: rgba(0, 255, 0, 0.5);
  text-align: center;
  width: 600px;
  height: 200px;
  padding-top: 90px;
  display: block;
  margin: 20px auto;
  position: relative;
}

.drop-input {
  width: 200px;
  height: 40px;
}

.drag-enter {
  border: solid 5px red;
}

.drop-container span.title {
  display: block;
  position: absolute;
  top: 10%;
  left: 50%;
  width: 200px;
  height: 20px;
  margin-left: -100px;
  margin-top: -10px;
}

.drop-container div {
  position: relative;
  z-index: 2;
}
&#13;
<script src="//code.angularjs.org/1.4.8/angular.js"></script>
<script src="//rawgit.com/fatlinesofcode/ngDraggable/master/ngDraggable.js"></script>

<body ng-app="app">
  <div ng-controller="controller">

    <div class="row">
      <h1>ngDraggable Example</h1>
    </div>

    <div ng-drop="true" ng-drop-success="onDropCompleteRemove($data,$event)">
      <ul class="draggable-objects">
        <li ng-repeat="obj in listItems">
          <div ng-drag="true" ng-drag-data="obj" data-allow-transform="true" class="item"> {{obj.title}} </div>
        </li>
      </ul>
    </div>

    <hr/>
    <div ng-drop="true" ng-drop-success="onDropComplete($data,$event)" class="drop-container">
      <span class="title">Drop area</span>

      <div ng-repeat="obj in droppedObjects" ng-drag="true" ng-drag-data="obj" ng-drag-success="onDragComplete($data,$event)" class="item">
        {{obj.title}}
      </div>
    </div>

    <hr/>
    <div class="container">
      Drop on input:
      <input ng-model="input.name" class="drop-input" ng-drop="true" ng-drop-success="onDropCompleteInput($data,$event)">
    </div>

    <br>
    <hr/>
    <pre>listItems = {{listItems|json}}</pre>
    <pre>input = {{input|json}}</pre>
    <pre>droppedObjects = {{droppedObjects|json}}</pre>
  </div>
</body>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

<!DOCTYPE html>
<html>

<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script src="https://code.angularjs.org/1.4.9/angular.js"></script>
<script src="https://cdn.jsdelivr.net/angular.dragdrop/1.07/angular-dragdrop.min.js"></script>

<body>
    <div ng-app="myApp" ng-controller="MyController">
        <div id="products">
            <h1 class="ui-widget-header">Products</h1>
            <div id="catalog">
                <div>
                    <ul>
                        <li ng-repeat='item in list1' ng-show="item.title" data-drag="true" data-jqyoui-options="{revert: 'invalid', helper: 'clone'}" ng-model="list1" jqyoui-draggable="{index: {{$index}}, animate: true, placeholder: 'keep'}">{{item.title}}</li>
                    </ul>
                </div>
            </div>
        </div> 


    <div id="cart">
        <h1 class="ui-widget-header">Shopping Cart</h1>
        <div class="ui-widget-content">
            <ol data-drop="true" ng-model='list4' jqyoui-droppable="{multiple:true}">
                <li ng-repeat="item in list4 track by $index" ng-show="item.title" data-drag="true" data-jqyoui-options="{revert: 'invalid', helper: 'clone'}" ng-model="list4" jqyoui-draggable="{index: {{$index}},animate:true}">{{item.title}}</li>
                <li class="placeholder" ng-hide="hideMe()">Add your items here</li>
            </ol>
        </div>
    </div>

    </div>

<script>
var app = angular.module('myApp', ['ngDragDrop']);

app.controller('MyController', function ($scope,$http,$sce) 
{
    $scope.list1 = [{'title': 'Lolcat Shirt'},{'title': 'Cheezeburger Shirt'},{'title': 'Buckit Shirt'}];

    $scope.list4 = [];

    $scope.hideMe = function() 
    {
        return $scope.list4.length > 0;
    }
});

</script>
</body>
</html>

您必须在 data-jqyoui-options

中使用帮助:&#39;克隆&#39;