Reputation: 4490
I have a sortable-wrapper directive that allow moving an item inside a list and from a list to another.
With an array container:
$scope.container = [
[{id: '1.1'}, {id: '1.2'}, {id: '1.3'}],
[{id: '2.1'}, {id: '2.2'}, {id: '2.3'}]
]
I use the directive like this:
<div ng-repeat="array in container">
<ul sortable>
<li ng-repeat="item in array">{{ item.id }}</li>
</ul>
</div>
When an item is dropped into a list, I have to update items backend side and insert the moved item that is returned by the backend at the right array/index:
$scope.move = function (from, fromIndex, to, toIndex) {
$http.post(url, data).success(function(movedItem) {
from.splice(fromIndex, 1)[0];
to.splice(toIndex, 0, movedItem);
});
}
This directive was working well until the version 1.2.0-rc.2, since 1.2.0-rc.3 I get this error when moving an item :
TypeError: Cannot call method 'insertBefore' of null
at http://code.angularjs.org/1.2.1/angular.js:3857:22
at forEach (http://code.angularjs.org/1.2.1/angular.js:303:18)
at Object.enter (http://code.angularjs.org/1.2.1/angular.js:3856:9)
at http://code.angularjs.org/1.2.1/angular.js:18828:26
at publicLinkFn (http://code.angularjs.org/1.2.1/angular.js:5443:29)
at boundTranscludeFn (http://code.angularjs.org/1.2.1/angular.js:5555:21)
at controllersBoundTransclude (http://code.angularjs.org/1.2.1/angular.js:6145:18)
at ngRepeatAction (http://code.angularjs.org/1.2.1/angular.js:18826:15)
at Object.$watchCollectionAction [as fn] (http://code.angularjs.org/1.2.1/angular.js:11347:11)
at Scope.$digest (http://code.angularjs.org/1.2.1/angular.js:11443:27)
Here is a plunker that reproduce the error: http://plnkr.co/edit/bAD8z2KdW34a7hkhdyiu?p=preview
Any thought ?
Upvotes: 0
Views: 758
Reputation: 4490
Finally, I change my implementation to use the angular-ui ui-sortable module. The angular 1.2 branch takes into account the changes of 1.2 version of the ng-repeat directive. See the pull request.
Upvotes: 0
Reputation: 40296
Use this:
<li ng-repeat="item in array track by item.id">{{ item.id }}</li>
Why?
I think you are creating items anew (getNewItemFromBackend(item)
) once their position is changed. Because ngRepeat
is tracking them by object equality, once an object leaves the list, Angular cannot find it to insert the DOM element. I am not 100% satisfied with this explanation, but it is roughly what is going on.
Upvotes: 1