Hier ist Ihre JS Bin sortierbar Komponente:
App.MyListComponent = Ember.Component.extend({
tagName: 'ul',
didInsertElement() {
let opts = {};
opts.update = this.updateList.bind(this);
this.$().sortable(opts);
},
updateList() {
this.$().sortable('cancel');
Ember.run.next(() => {
this.get('content').removeAt(0);
});
}
});
Und dann ist dies Ihr JS Bin updated mit Code aus dem ember-ui-sortable repo der folgenden:
App.MyListComponent = Ember.Component.extend({
tagName: 'ul',
uiOptions: [
'axis',
'containment',
'cursor',
'cursorAt',
'delay',
'disabled',
'distance',
'forceHelperSize',
'forcePlaceholderSize',
'grid',
'handle',
'helper',
'opacity',
'placeholder',
'revert',
'scroll',
'scrollSensitivity',
'scrollSpeed',
'tolerance',
'zIndex'
],
destroySortable: Ember.on('willDestroyElement', function() {
this.$().sortable('destroy');
}),
initSortable: Ember.on('didInsertElement', function() {
let opts = {};
['start', 'stop'].forEach((callback) => {
opts[callback] = Ember.run.bind(this, callback);
});
this.$().sortable(opts);
this.get('uiOptions').forEach((option) => {
this._bindSortableOption(option);
});
}),
contentObserver: Ember.observer('content.[]', function() {
Ember.run.scheduleOnce('afterRender', this, this._refreshSortable);
}),
move(oldIndex, newIndex) {
let content = this.get('content');
let mutate = this.getWithDefault('mutate', true);
let item = content.objectAt(oldIndex);
if (content && mutate) {
content.removeAt(oldIndex);
content.insertAt(newIndex, item);
}
if(!mutate){
this.attrs.moved(item, oldIndex, newIndex);
}
},
start(event, ui) {
ui.item.data('oldIndex', ui.item.index());
},
stop(event, ui) {
const oldIndex = ui.item.data('oldIndex');
const newIndex = ui.item.index();
this.move(oldIndex, newIndex);
},
_bindSortableOption: function(key) {
this.addObserver(key, this, this._optionDidChange);
if (key in this) {
this._optionDidChange(this, key);
}
this.on('willDestroyElement', this, function() {
this.removeObserver(key, this, this._optionDidChange);
});
},
_optionDidChange(sender, key) {
this.$().sortable('option', key, this.get(key));
},
_refreshSortable() {
if (this.isDestroying) { return; }
this.$().sortable('refresh');
}
});
Wie Sie es sehen Es ist ziemlich viel mehr im Vergleich zu Ihrem Original, so dass Sie sehen können, was Sie verpasst haben und hoffentlich hilft Ihnen das. Es könnte eine gute Idee sein, diese Komponente Addon über Ember-CLI zu installieren, aber auch konkurrierende Lösungen wie ember-sortable und andere zuerst mit etwas wie ember-observer aussehen.
Ich habe keine Antwort auf Ihre Frage, aber ich kann Ihnen zumindest den POV vorschlagen, mit dem Sie Ihre Situation analysieren sollten. Das jQuery UI Sortable-Plugin beruht auf der direkten DOM-Manipulation, die passieren würde, da Callbacks, die von ihm registriert werden, auf Mausereignissen von Benutzern ausgelöst werden. Ember auf der anderen Seite verwendet HTMLbars, die auch eine DOM-Manipulationslogik haben, die viel ausgeklügelter ist und in ein solches Verhalten eingetaucht werden sollte. Was Sie tun sollten, ist eine direkte DOM-Manipulation zu vermeiden und das 'content'-Array auf der Komponente mutieren. Das ist Ember Art Dinge zu tun. – canufeel
Ich denke, ich sollte auch hinzufügen, dass wenn du es gleich von Anfang an willst, du das 'content' Array 'losbinden' solltest, bevor du tatsächlich mutierst, damit du nicht in einer datenbindenden Hölle landest. – canufeel
@canufeel Sie haben Recht, das ist die DOM-Frage. Wenn ich die Aktualisierung in der Komponente wie in [JS Bin] (http://emberjs.jsbin.com/huciqinoho/edit?html,js,output) simuliere, funktioniert es. Aber ich denke, es muss eine Art Ember-Art gegeben haben, es zu tun. Vielleicht ist es ein Glimmer-Problem, das nach DOM, das von jQuery UI verändert wurde, keinen ordentlichen Unterschied machen kann? – Lucas