I think you've fooled yourself into thinking that Angular is managing this list for you (and me too, for the past hour ;) ). Because of the jQuery plugins you're using, the DOM for that sortable <ul>
doesn't appear to be under Angular's control anymore. They probably re-rendered something at some point, wrapped it in a container, etc. But that means you are responsible for the DOM. After the drop, you need to re-insert the removed elements (draggedElements
) into the correct position in the list.
Alternatively... you can trick Angular into managing the list for you.
First, add ng-if="cities"
to your sortable <ul>
, then add this code at the end of your drop
callback:
var temp = scope.collection.slice(0);
scope.$apply(function(scope) {
while (scope.collection.length) scope.collection.pop();
});
scope.$apply(function(scope) {
for (var i = 0; i < temp.length; i++) scope.collection.push(temp[i]);
});
The ng-if
directive causes angular to re-render the inner components (and re-initialize any inner directives) anytime the value changes from false
to true
. In this case, we use two calls to $apply
to first give the collection a falsy value, and then restore its contents. This trips the ng-if
wire and causes the list to re-render.
Example: http://jsfiddle.net/colllin/8dcXB/