Javascript 基于特定条件的拖放列表

Javascript 基于特定条件的拖放列表,javascript,jquery,angularjs,drag-and-drop,Javascript,Jquery,Angularjs,Drag And Drop,我正在使用AngularJS项目的角度拖放列表创建两个列表,允许我执行以下操作: <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-dra

我正在使用AngularJS项目的角度拖放列表创建两个列表,允许我执行以下操作:

<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
        }
将项目从列表A拖动到列表B 将项目从列表B拖动到列表A 对列表A中的项目重新排序 对列表B中的项目重新排序 通过图书馆网站上的一个简单例子,我可以看出这四个条件很容易实现。然而,当我想介绍稍微复杂一点的行为时,事情开始变得复杂起来:

当将项目从列表A拖到列表B时,我希望通过dnd drop回调可以轻松实现。这对我来说很有效 当将项目从列表B拖到列表A时,我不希望发生任何事情,除了常规的下降,即项目在列表A中结束,并且什么也没有发生。这对我来说很有效 当对列表A中的项目进行重新排序时,如果项目被重新放置到列表中的新位置,则不应发生任何事情,即使项目被放置回其原始位置,这也是我遇到问题的地方-请参阅下面的进一步解释 在对列表B中的项目重新排序时,如果项目被重新放置到列表中的新位置,则不应发生任何事情,即使该项目被放置回其原始位置。这对我来说很有效 我在很大程度上修改了上面提供的示例链接中使用的示例代码。我遇到的问题是,当我将项目从列表A移动到列表B时,我希望执行的操作也在我重新排列列表A中的项目时发生

我拥有的当前设置/伪代码如下:

<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
        }
我的名单:

$scope.models.lists = {
    "A": [],
    "B": []
}
我用从数据库中提取的信息填充这些列表。列表中的每个项还具有一个属性,用于跟踪该项有多少子项

我的标记如下所示:

<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
        }
我的回调如下所示:

<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
        }
如果有人能在这方面帮助我,我将非常感激


谢谢

查看自述文件,无论是否在同一列表中,dnd drop事件都会触发任何drop


按照现在的脚本,您需要检查事件或将一些附加信息传递到回调中,以确定事件触发的列表。

如果您没有完全致力于该库,顺便说一句,该库不能与触摸屏一起使用,RubaXa的可排序性就是事实:


文档很丰富,性能很好,我希望在此之前我没有在其他DnD库上浪费时间。

嗨,我添加了一个dragstartCallback,用于在event.dataTransfer中设置变量 有关我的拖曳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中,我只检查是列表A还是列表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>
拖放列表在ng repeat的索引上工作

筛选列表 现在,如果我们用| filter:searchFilter代码为“a”制作一个过滤器 我会列在这个名单上

拖动dddaaa时,索引将为1而不是3 因此,在listB中删除时,它不会从listA中删除 因为索引与未筛选列表不同

相反,如果使用ng show=条件 它将保持列表的原始索引不被过滤


我不受图书馆的约束,所以我非常乐意去看看。不过,我无法很快看出库是否支持我给定的用例。你能解释这一点吗?我不完全清楚你在原始问题中试图做什么,但在我刚刚拼凑的这个例子中应该有一些子集:。当从A移动到B时,或者当属性计数器在列表之间移动时,它会触发警报,在这种情况下,移动的项目超过了您设置的阈值。哇,我真的很感谢您在这里所做的努力!我不确定我怎么能不那么模棱两可地说出我的意图,但你所举的例子似乎满足了我的要求。我只想能够从A->A,B->B,B->A移动而不会收到警报,当从A->B移动时,我只想在满足特定条件时发出警报,否则只需像正常情况一样进行常规拖放。将此标记为您提供的已接受答案确实回答了我的问题。你到底是如何在几乎没有文档的情况下使用angular指令的?你是不是刚读了源代码,然后从那里算出来的?如果是这样,干得好!现在,当我阅读您的消息时,已经不再是半夜了,它不再那么模棱两可了:-我已经对这个特定的指令进行了一段时间的修补,但实际上只是使用了作者代码中选项下的注释,然后深入到事件回调中,看看传递了什么。很高兴能帮忙。