没有 angular-magic 可以帮助您找到新元素或移动元素的位置,但使用 jQuery 很容易做到。我创建了一个 jQueryUI-demo 示例,在指令中包装可排序和可拖动:
http://plnkr.co/edit/aSOlqR0UwBOXgpQSFKOH?p=preview
<ul>
<li my-draggable="#sortable" class="ui-state-highlight">Drag me down</li>
</ul>
<ul my-sortable id="sortable">
<li class="ui-state-default" ng-repeat="item in items">{{item.name}}</li>
</ul>
my 的值my-draggable
是对应元素的 id my-sortable
。my-draggable 在其他方面非常简单:
app.directive('myDraggable',function(){
return {
link:function(scope,el,attrs){
el.draggable({
connectToSortable: attrs.myDraggable,
helper: "clone",
revert: "invalid"
});
el.disableSelection();
}
}
})
在my-sortable
我听deactivate
指示元素已被删除的事件。from
是数组中作为 ng-repeat 源的元素的位置。ng-repeat 为每个元素创建一个子作用域,其中 $index 变量指示当前元素在数组中的位置。如果 $index 未定义,我知道它是一个新元素(可能是确定这一点的更好方法,但它适用于本示例)。to
是项目的新位置。如果移动了现有元素,我会发出“my-sorted”事件,如果添加了新元素,则会发出“my-created”事件。
app.directive('mySortable',function(){
return {
link:function(scope,el,attrs){
el.sortable({
revert: true
});
el.disableSelection();
el.on( "sortdeactivate", function( event, ui ) {
var from = angular.element(ui.item).scope().$index;
var to = el.children().index(ui.item);
if(to>=0){
scope.$apply(function(){
if(from>=0){
scope.$emit('my-sorted', {from:from,to:to});
}else{
scope.$emit('my-created', {to:to, name:ui.item.text()});
ui.item.remove();
}
})
}
} );
}
}
})
在控制器中,我创建 items-array 并监听事件:
$scope.items = [
{name:'Item 1'},
{name:'Item 2'},
{name:'Item 3'},
{name:'Item 4'},
];
$scope.$on('my-sorted',function(ev,val){
// rearrange $scope.items
$scope.items.splice(val.to, 0, $scope.items.splice(val.from, 1)[0]);
})
$scope.$on('my-created',function(ev,val){
// create new item at position
$scope.items.splice(val.to, 0,
{name:'#'+($scope.items.length+1)+': '+val.name});
})
如您所见,当您添加或移动元素时,范围内的模型会更新。
这些指令不是很通用 - 您可能需要进行一些调整才能让它们与您的应用程序一起使用。