Search code examples
javascriptangularjsdata-bindingclonerubaxa-sortable

Removing the "data-binding" between drag and dropped (cloned) items in an AngularJS app


I'm using the Sortable library (https://github.com/RubaXa/Sortable) to create a drag and drop relationship between two lists (models). For clarity's sake, let's call one SourceModel and DestinationModel.

Items are pulled (and cloned) from SourceModel to DestinationModel. The items that are dropped into DestinationModel are rendered with an ng-repeat (listItem in DestinationModel track by $index) which is tracked by index.

The problem that I'm having is when you clone the item, any of the resulting clones of the same type are "data-bound," so since I'm using contenteditable to manipulate the object, all of the objects of the same type are changed, including the original. (So subsequent drags of that type are also changed)

You can see the problem here:

binding issue

The two top components were dragged in during this session, and when you change one, you change both. However, the object that already existed on page load is not bound, and thus does not change with the changes in the other two.

Once you save the configuration and refresh, since the items are tracked by index, everything works independently and fine.

I've tried using the onAdd() callback within Sortable to do a deep copy of the item on add, however that did not work.

https://github.com/RubaXa/Sortable#options

onAdd: function (e, c) {
    c = angular.copy(c);
},

I've also tried "cleansing" the model of the hashkeys after the drop by forcing the array through the following function:

model.cleanseStack = function() {
  stack = JSON.parse(angular.toJson(stack));
};

However, I haven't had much luck with that either - the objects are still bound.

How can I make sure I break the data-binding that exists between the objects. I do still need it bound independently between the markup and the model, however, they should not be bound together.

Note: I'm not using jQuery. At most, I have access to jqlite as part of the AngularJS framework.


Solution

  • This was fixed within the Sortable library itself here:

    https://github.com/RubaXa/Sortable/commit/fff7711238f9fc77fb1329aa5417aff4fdfbe0f0