根据特定条件拖放列表
Posted
技术标签:
【中文标题】根据特定条件拖放列表【英文标题】:Drag and drop lists based on certain conditions 【发布时间】:2015-10-09 04:38:09 【问题描述】:我正在为我的 AngularJS 项目使用 angular-drag-and-drop-lists (https://github.com/marceljuenemann/angular-drag-and-drop-lists) 来创建两个允许我执行以下操作的列表:
-
将项目从列表 A 拖到列表 B
将项目从列表 B 拖到列表 A
对列表 A 中的项目重新排序
重新排序列表 B 中的项目
使用图书馆网站 (http://marceljuenemann.github.io/angular-drag-and-drop-lists/demo/#/simple) 上的一个简单示例,我可以看到这四个条件很容易实现。然而,当我想引入稍微复杂一点的行为时,事情就开始变得棘手了:
-
当将项目从列表 A 拖到列表 B 时,我希望发生一些事情(通过 dnd-drop 回调很容易实现。这目前适用于我
当将项目从列表 B 拖到列表 A 时,我不希望发生除常规放置之外的任何事情(即项目在列表 A 中结束并且没有任何花哨的事情发生)。 目前对我有用
对列表 A 中的项目进行重新排序时,将项目重新放入列表中的新位置时不会发生任何事情(即使它被放回原来的位置)这是我遇到问题的地方- 更多解释见下文
对列表 B 中的项目进行重新排序时,将项目重新放入列表中的新位置时不会发生任何事情(即使它被放回其原始位置)。 目前对我有用
我在很大程度上调整了上面提供的示例链接中使用的示例代码。我遇到的问题是,当我将列表 A 中的项目重新排序时,我想要执行的操作也发生在列表 A 中。
我目前的设置/伪代码如下:
我的清单:
$scope.models.lists =
"A": [],
"B": []
我用从数据库中提取的信息填充这些列表。列表中的每个项目还有一个属性,用于跟踪该项目有多少 children
。
我的标记如下所示:
<ul dnd-list="list"
dnd-allowed-types="['itemType']"
dnd-drop="myCallback(event, index, item, external, type, 'itemType')">
<li ng-repeat="item in list | filter:searchText"
dnd-draggable="item"
dnd-moved="list.splice($index, 1)"
dnd-effect-allowed="move"
dnd-selected="models.selected = item"
dnd-type="'itemType'"
ng-class="'selected': models.selected === item"
ng-dblclick="editProperties();">
item.label + ' - ' + item.description
</li>
</ul>
我的回调如下所示:
$scope.myCallback= function(event, index, item, external, type, allowedType)
// If the item in question has no children then we don't need to do anything special other than move the item.
if (item.children.length == 0)
return item;
// If moving items around list B then just move them.
for (var i = 0; i < $scope.models.lists.B.length; i++)
if (item.label === $scope.models.lists.B.[i].label)
return item;
// I only want this code to execute if we know we are moving from list A to list B and the item in question has > 0 children.
if (item.children.length > 0)
// Code that I want to execute only when moving from list A to list B goes here
如果有人能够帮助我,我将非常感激。
谢谢!
【问题讨论】:
【参考方案1】:如果您不完全致力于该库(顺便说一句,它不适用于触摸屏)RubaXa 的 Sortable 就是事实:Sortable
文档很强大,性能非常好,我希望在此之前我没有将时间浪费在其他 DnD 库上。
【讨论】:
我不受图书馆的约束,所以我很乐意去看看。不过,我不能很快看出我给定的用例是否会得到库的支持。你能对此有所了解吗? 我不是完全清楚你在原始问题中要做什么,但它的一些子集应该在我刚刚放在一起的这个例子中:@ 987654322@。当从 A 移动到 B 时,或者在列表之间移动时,当被移动项目的属性(在本例中为计数器)超过您设置的阈值时,它将触发警报。 哇,我真的很感谢你在这里付出的努力!我不确定我如何才能对我的意图不那么模棱两可,但你提出的例子似乎满足了我正在寻找的东西。我只想能够从 A->A、B->B、B->A 移动而不会收到警报,并且从 A->BI 移动时只希望在满足特定条件时发出警报,否则只需执行像平常一样进行常规拖放。 将此标记为已接受的答案,因为您提供的确实回答了我的问题。您到底是如何研究出如何在(几乎)零文档的情况下使用角度指令的?您是否刚刚阅读了源代码并从那里开始工作?如果是这样,干得好! 现在阅读您的消息时不再是半夜,它不再那么模棱两可了 :-) 我一直在修改这个特定的指令一段时间,但实际上只是使用选项(github.com/RubaXa/Sortable)下作者代码中的 cmets,然后深入了解事件回调以查看传递的内容。很高兴能提供帮助。【参考方案2】:查看自述文件,dnd-drop
事件会触发任何丢弃 - 无论它是否在同一个列表中。
按照您现在的脚本,您需要检查事件(或将一些附加信息传递到您的回调中)以确定事件触发的列表。
【讨论】:
【参考方案3】:嗨,我添加了一个在 event.dataTransfer 中设置变量的 dragstartCallback 有关我拖动的 obj 的来源/来源的信息:
$scope.dragstartCallback = function(event)
var id = event.target.id;
var parent = $('#' + event.target.id).closest('ul')[0].id;
var group = $('#' + event.target.id).closest('div')[0].id;
event.dataTransfer.setData("id", id);
event.dataTransfer.setData("parent", parent);
event.dataTransfer.setData("group", group);
return true;
在 dropCallback 中,我只检查是 List A 还是 List B
$scope.dropCallback = function(event, index, item, external, type, allowedType)
$scope.logListEvent('dropped at', event, index, external, type);
var idDivSource = event.dataTransfer.getData("parent");
var idDivDestination = $(event.target).closest('ul')[0].id;
var groupSource = event.dataTransfer.getData("group");
var groupDestination = $('#' + event.target.id).closest('div')[0].id;
if(groupSource == groupDestination)
if(idDivSource != idDivDestination)
if(idDivDestination == 'IDLISTB')
return item?
if(idDivDestination == 'IDLISTA')
DO Something else
DO Something else
html代码:
<div class="associated-drag-and-drop DnD" id="GROUP-MyD&D1" ng-repeat="(listName, list) in models.lists" flex="">
<ul dnd-list="list" id="listName" dnd-drop="dropCallback(event, index, item, external, type, 'containerType')" flex="">
<md-list-item class="associated-list__item" ng-repeat="item in list | filter:searchFilter" id="item.id"
dnd-dragover="dragoverCallback(event, index, external, type)"
dnd-dragstart="dragstartCallback(event)"
dnd-draggable="item"
dnd-moved="list.splice($index, 1)"
dnd-effect-allowed="move"
dnd-selected="models.selected = item"
ng-class="'selected': models.selected === item"
class="noright associated-list__item"
>
CONTENT
</md-list-item>
</ul>
</div>
不要使用这种类型的过滤器“| filter:searchFilter” 但是使用 ng-show="并把条件放在这里" 替代更改 dnd-moved="list.splice($index, 1)" 中对 $index 的引用
如果您不进行此更改,则拖放时过滤列表会出现问题
示例 未过滤列表 您将在 2 ng-repeat 中有 2 个数组
ListA ListB
index1 of value index2 of value
ng-repeat of list ng-repeat of list
0 aaa 0 ppp
1 bbb 1 qqq
2 ccc 2 www
3 dddaaa 3 eeerrr
4 eeeccc 4 mmmwww
ecc... ecc...
拖放列表对 ng-repeat 的索引起作用
过滤列表 现在,如果我们使用“| filter:searchFilter”代码为“a”制作过滤器 angular 会列出这个列表
List A List B
0 aaa
1 dddaaa
拖动“dddaaa”时的索引将是 1 而不是 3 所以当它被放到 listB 中时,它不会从 listA 中删除 因为索引与非过滤列表不同
如果你使用 ng-show="condition" 它将保持列表的原始索引不被过滤
<md-list-item ng-repeat="item in list"
ng-show="condition">
</md-list-item>
我的物品清单:
$scope.models =
lists:
"LISTA": [1,2,3],
"LISTB": [1,2,3]
;
【讨论】:
以上是关于根据特定条件拖放列表的主要内容,如果未能解决你的问题,请参考以下文章