简体   繁体   English

列表之间的AngularJS拖放以1.2分隔

[英]AngularJS Drag and Drop between lists breaks with 1.2

I've been using an implementation of this Drag and Drop with AngularJS and jQuery UI: 我一直在使用AngularJS和jQuery UI的拖放实现:

http://www.smartjava.org/examples/dnd/double.html http://www.smartjava.org/examples/dnd/double.html

With AngularJS 1.0.8 it works flawlessly. 使用AngularJS 1.0.8,它可以完美工作。 With 1.2.11, it doesn't. 对于1.2.11,事实并非如此。

When using AngularJS 1.2 and dragging an item from the left list to the right one the model for the destination list updates correctly. 使用AngularJS 1.2并将项目从左侧列表拖到右侧时,目标列表的模型会正确更新。 However the DOM doesn't update correctly. 但是,DOM无法正确更新。 Here is the directive that's being used from the example: 这是示例中使用的指令:

app.directive('dndBetweenList', function($parse) {

  return function(scope, element, attrs) {

    // contains the args for this component
    var args = attrs.dndBetweenList.split(',');
    // contains the args for the target
    var targetArgs = $('#'+args[1]).attr('dnd-between-list').split(',');

    // variables used for dnd
    var toUpdate;
    var target;
    var startIndex = -1;

    // watch the model, so we always know what element
    // is at a specific position
    scope.$watch(args[0], function(value) {
        toUpdate = value;
    },true);

    // also watch for changes in the target list
    scope.$watch(targetArgs[0], function(value) {
        target = value;
    },true);

    // use jquery to make the element sortable (dnd). This is called
    // when the element is rendered
    $(element[0]).sortable({
        items:'li',
        start:function (event, ui) {
            // on start we define where the item is dragged from
            startIndex = ($(ui.item).index());
        },
        stop:function (event, ui) {
            var newParent = ui.item[0].parentNode.id;

            // on stop we determine the new index of the
            // item and store it there
            var newIndex = ($(ui.item).index());
            var toMove = toUpdate[startIndex];

            // we need to remove him from the configured model
            toUpdate.splice(startIndex,1);

            if (newParent == args[1]) {
                // and add it to the linked list
                target.splice(newIndex,0,toMove);
            }  else {
                toUpdate.splice(newIndex,0,toMove);
            }

            // we move items in the array, if we want
            // to trigger an update in angular use $apply()
            // since we're outside angulars lifecycle
            scope.$apply(targetArgs[0]);
            scope.$apply(args[0]);
        },
        connectWith:'#'+args[1]
    })
  }
});

Does something need to be updated for this to work properly with Angular 1.2? 是否需要进行一些更新才能使其与Angular 1.2一起正常工作? I feel like it has something to do with the scope.$apply but am not sure. 我觉得这与scope.$apply但不确定。

I see this is an older question, but I recently ran into the exact same issue with the Drag and Drop example. 我看到这是一个比较老的问题,但是最近我在“拖放”示例中遇到了完全相同的问题。 I don't know what has changed between angular 1.0.8 and 1.2, but it appears to be the digest cycle that causes problems with the DOM. 我不知道在角度1.0.8和1.2之间发生了什么变化,但这似乎是导致DOM问题的摘要循环。 scope.$apply will trigger a digest cycle, but scope.$apply in and of itself is not the issue. scope.$apply将触发摘要循环,但是scope.$apply本身并不是问题。 Anything that causes a cycle can cause the DOM t get out of sync with the model. 任何导致周期的事情都可能导致DOM与模型不同步。

I was able to find a solution to the the problem using the ui.sortable directive. 我可以使用ui.sortable指令找到该问题的解决方案。 The specific branch that I used is here: https://github.com/angular-ui/ui-sortable/tree/angular1.2 . 我使用的特定分支在这里: https : //github.com/angular-ui/ui-sortable/tree/angular1.2 I have not tested with other branches. 我尚未与其他分支机构进行过测试。

You can view a working example here: 您可以在此处查看工作示例:

http://plnkr.co/edit/atoDX2TqZT654dEicqeS?p=preview http://plnkr.co/edit/atoDX2TqZT654dEicqeS?p=preview

Using the ui-sortable solution, the 'dndBetweenList' directive gets replaced with the ui-sortable directive. 使用ui-sortable解决方案,将'dndBetweenList'指令替换为ui-sortable指令。 Then there are a few changes to make. 然后要进行一些更改。

In the HTML 在HTML中

<div class="row">
<div class="span4 offset2">
      <ul ui-sortable="sortableOptions" ng-model="source" id="sourceList"  ng-class="{'minimalList':sourceEmpty()}" class="connector">
        <li class="alert alert-danger nomargin" ng-repeat="item in source">{{item.value}}</li>
      </ul>
    </div>
<div class="span4">
      <ul ui-sortable="sortableOptions" id="targetList" ng-model="model" ng-class="{'minimalList':sourceEmpty()}" class="connector">
        <li class="alert alert-info nomargin" ng-repeat="item in model">{{item.value}}</li>
      </ul>
    </div>
  </div>

Note the dnd-between-list directive is no longer needed and is replaced with the ui-sortable. 请注意,不再需要dnd-between-list指令,并将其替换为ui-sortable。

In the module inject the ui-sortable, and in the controller specify that sortable options. 在模块中注入ui-sortable,并在控制器中指定该sortable选项。 The sortable accepts the same options as the jquery sortable. sortable接受与jquery sortable相同的选项。

app.js app.js

var app = angular.module('dnd', ['ui.sortable']); 

ctrl-dnd.js CTRL-dnd.js

$scope.sortableOptions  = {
    connectWith: '.connector'
}

Only the additions to the controller are shown. 仅显示控制器的添加项。 Note that I added a .connector class on the ul. 请注意,我在ul上添加了.connector类。 In the sortable I use .connector for the connectWith option. 在可排序中,我将.connector用于connectWith选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM