角度拖放(使用 jQuery UI) - 禁用交换
Posted
技术标签:
【中文标题】角度拖放(使用 jQuery UI) - 禁用交换【英文标题】:angular dragdrop (using jQuery UI) - disable swapping 【发布时间】:2016-05-05 02:24:33 【问题描述】:我在交换拖放的元素时遇到问题。
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>
问题:
当我拖放一个 list item 1
时,list item 1
的 name
属性属于 input
模型。但在list item 1
中不再可用。实际上,list item 1
的值在我将其放入 input
之后变为 undefined || null
。如果我现在尝试在 input
中拖放 list item 2
项目 - 值交换(list item 1 = undefined || null ?
和 list item 2 = list item 1 value
和 input
模型等于列表项目 2 值`。所以一切都洗牌。
我需要什么: 我需要在输入中拖放列表项,避免丢失列表项中的值。每次我在输入中删除列表项时,我都需要将它的值绑定到输入。
开箱即用 我可以更改拖放库,甚至使用源代码,但库是更好的选择。我接受几乎所有没有破坏任何良好代码标准的良好工作答案(我的意思是我需要不会破坏其他代码并且具有良好结构的代码)。
【问题讨论】:
【参考方案1】:我建议使用 ngDraggable,一个不依赖 jQuery 或 jQuery-ui 的 Angular 模块。
以下是一个有效的 sn-p 或查看我的Codepen:
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);
);
*
-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;
<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>
【讨论】:
我真的很喜欢这个库及其行为,但是当我在 angular-bootstrap-ui (Tabs) 中使用它时 - 选项卡标题文本绑定不正确,直到我进行选项卡选择/删除更改。跨度> 你确定吗?我尝试在选项卡式应用程序中添加上面的代码,但看不到任何问题;检查plnkr.co/edit/Z1pMBMOMvUF8ATfKgVzh 是的,我不知道为什么会这样,我现在解决它,但我会尝试修复它。 Actullayuib-tabs
尝试将active
属性设置为ng-drag="true"
。它抛出cannot set property 'active' to string 'true'
..奇怪..
如果您可以提供该问题的示例(即 Plunker),我可以帮助您【参考方案2】:
<!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
中使用 helper: 'clone'【讨论】:
以上是关于角度拖放(使用 jQuery UI) - 禁用交换的主要内容,如果未能解决你的问题,请参考以下文章
使用 jQuery UI 可排序和引导网格复制 Hubspots 拖放表单构建器 UI