我一直在使用AngularJS和jQuery UI的拖放实现:
http://www.smartjava.org/examples/dnd/double.html
使用AngularJS 1.0.8,它可以完美运行。在1.2.11中,它没有。
使用AngularJS 1.2并将项目从左侧列表拖动到右侧列表时,目标列表的模型会正确更新。但是DOM没有正确更新。以下是从示例中使用的指令:
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]
})
}
});
是否需要更新某些内容才能使其与Angular 1.2一起正常使用?我觉得它与scope.$apply
有关,但我不确定。
答案 0 :(得分:1)
我认为这是一个较旧的问题,但我最近遇到了与拖放示例完全相同的问题。我不知道角度1.0.8和1.2之间有什么变化,但它似乎是导致DOM问题的摘要周期。 scope.$apply
会触发摘要周期,但scope.$apply
本身并不是问题。导致循环的任何事情都可能导致DOM与模型失去同步。
我能够使用ui.sortable指令找到问题的解决方案。我使用的具体分支在这里:https://github.com/angular-ui/ui-sortable/tree/angular1.2。我还没有和其他分支机构一起测试过。
您可以在此处查看工作示例:
http://plnkr.co/edit/atoDX2TqZT654dEicqeS?p=preview
使用ui-sortable解决方案,'dndBetweenList'指令被ui-sortable指令替换。然后有一些变化。
在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>
请注意,不再需要dnd-between-list指令,并将其替换为ui-sortable。
在模块中注入ui-sortable,并在控制器中指定可排序的选项。 sortable接受与jquery sortable相同的选项。
app.js
var app = angular.module('dnd', ['ui.sortable']);
CTRL-dnd.js
$scope.sortableOptions = {
connectWith: '.connector'
}
仅显示控制器的添加内容。请注意,我在ul上添加了一个.connector类。在sortable中,我使用.connector作为connectWith选项。