Reputation: 41
i have a problem with reordering item in a table.
i'm using angularJs + ngTable and ui-sortable.
The problem is that the reordered data ist displayed in wrong order after reloading. The data is correct and the order values are correct too but they are shown in wrong order. Its happening after reload the table/view after reordering the items. It also don't happen always. for example if i move:
1 to 4
5 to 2
1 to 8
3 to 1
2 to 6
should lead to following order:
4,3,1,6,7,5,8,2,9,10 but after reloading the items they are in this order:
4,1,3,6,7,5,9,10,8,2
But the items have their correct order values assigned.
You can check this out on plunker https://plnkr.co/edit/HIh0pnBBjLMzErHzKAd9
Reorder the items like described above and click on the button to reload the view.
I found out that its happening during the ng-repeat directive on this code block in angularJs: // if we have already seen this object, then we need to reuse the // associated scope/element
nextNode = previousNode;
// skip nodes that are already pending removal via leave animation
do {
nextNode = nextNode.nextSibling;
} while (nextNode && nextNode[NG_REMOVED]);
if (getBlockStart(block) !== nextNode) {
// existing item which got moved
$animate.move(getBlockNodes(block.clone), null, previousNode);
}
previousNode = getBlockEnd(block);
updateScope(block.scope, index, valueIdentifier, value, keyIdentifier, key, collectionLength);
There is something going on with wrong sibling, which leads to the move the data to different position. the data which is passed to ng-repeat seems correct. The objects have the correct new order value.
You could ask, why reload when data is display correctly? Well thats happening for example if someone want to sort by clicking the columns.
EDIT: It Seems the model for my list is not updated. if i use $scope.$apply() at the end of stop() it seems to work. This leads to performance issue when having more data due to calling $scope.$apply() when dropping every row. When i use $scope.$apply() outside of stop() it doesn't work. :(
i don't understand why i need to call $scope.apply because i am not changing the object outside of the scope.
so, the question is now how do i apply the model change without calling $scope.$apply() on every stop() event but only once at the end/before reloading the table? If i call $scope.$apply on btn click, it doesn't work.
EDIT/SOLVED: ok. the Problem with calling $apply() was that sortable was initialized through Jquery. If you use it correctly with ui-sortable directives it also call digest internally but then i dont need it manually. I also could solve my loading issue after refactoring some code. In the end that extra apply()/digest loop doesnt bother me anymore.
Upvotes: 3
Views: 354