Chris Conley
Chris Conley

Reputation: 1062

Best way to update CollectionView content after jQuery UI Sortable?

I've been able to get jQuery UI Sortable working in Ember.js thanks to @ghemton's safeClone method: Ember.js + jQuery UI Draggable Clone

I'm having trouble letting Ember know of the change though once the sort has completed. Right now, I'm using splice as suggested in Move an array element from one array position to another to move the item in the collection to its proper place. That works fine but I'm having an issue with window scrolling.

In this jsfiddle, http://jsfiddle.net/chrisconley/g4aE6/, if you scroll to the bottom, then reorder any of the elements, the window jumps back to the top. If you put a breakpoint in between propertyWillChange and propertyDidChange, you can see that Ember is removing all of the items from the view momentarily, which is causing the window to jump back to the top.

App.MySortableView = Em.CollectionView.extend({
  moveItem: function(fromIndex, toIndex){
    var items = this.get('content');
    this.propertyWillChange('content');
    item = items.splice(fromIndex, 1)[0];
    items.splice(toIndex, 0, item);
    this.propertyDidChange('content');
  }
});

Is there a way to notify Ember of the change without it removing and replacing the entire collection?

Updated Solution:

(Thanks to Christopher Swasey's answer below)

App.MySortableView = Em.CollectionView.extend({
  moveItem: function(fromIndex, toIndex){
    var items = this.get('content');
    item = items.objectAt(fromIndex);
    items.removeAt(fromIndex);
    items.insertAt(toIndex, item);
  }
});

Full example here: http://jsfiddle.net/chrisconley/NN35P/

Upvotes: 5

Views: 1328

Answers (1)

Christopher Swasey
Christopher Swasey

Reputation: 10562

You shouldn't be using JS standard library calls on objects like Array. These calls aren't trappable by Ember's bindings/observers. Instead, use the APIs defined by Ember, such as 'replace', 'objectAt', etc. to interact with arrays.

In this case, you'll want to swap out #splice with #replace.

Upvotes: 4

Related Questions