EmberJS计算排序属性与jQuery UI Sortable冲突

时间:2015-03-23 20:09:44

标签: ember.js jquery-ui-sortable

我遇到了使用EmberJS进行拖放排序功能的问题。

涵盖此问题的教程并未提供有关初始排序的任何帮助,我正在通过计算属性进行此操作。

sortedItems计算属性发生更改并且jQueryUI Sortable更新DOM时,我遇到的似乎是ember重新渲染之间的竞争条件。列表项目在排序时会重复或完全消失。

路线

import Ember from 'ember';

export default Ember.Route.extend({
  model: function() {
    return Ember.Object.create({
      id: 1,
      title: "Title",
      subtitle: "Subtitle",
      items: [
        Ember.Object.create({
          name: "Item 2",
          sortOrder: 2,
          id: 1
        }),
        Ember.Object.create({
          name: "Item 1",
          sortOrder: 1,
          id: 2
        }),
        Ember.Object.create({
          name: "Item 3",
          sortOrder: 3,
          id: 3
        })
      ]
    });
  }
});

控制器

import Ember from 'ember';

export default Ember.ObjectController.extend({

  sortProperties: [ 'sortOrder' ],
  sortedItems: Ember.computed.sort('model.items', 'sortProperties'),

  actions: {
    updateSortOrder: function(indexes) {
      this.get('items').forEach(function(item) {
        var index = indexes[item.get('id')];
        item.set('sortOrder', index);
      });
    }
  }

});

视图

import Ember from 'ember';

export default Ember.View.extend({

  didInsertElement: function() {
    var controller = this.get('controller');

    this.$(".item-list").sortable({
      update: function(event, ui) {
        var indexes = {};

        $(this).find('li').each(function(index) {
          indexes[$(this).data('id')] = index;
        });

        controller.send('updateSortOrder', indexes);
      }
    })
  }
});

模板

<h1>{{ title }}</h1>
<h2>{{ subtitle }}</h2>

<ul class="item-list">
  {{#each item in sortedItems }}
    <li data-id="{{ unbound item.id }}">
      name: {{ item.name }}<br />
      sortOrder: {{ item.sortOrder }}<br />
      id: {{ item.id }}
    </li>
  {{/each}}
</ul>

这是一个重现问题的Barebones Ember应用:https://github.com/silasjmatson/test-sortable

问题

有没有办法避免这种竞争条件或只在控制器初始化时排序一次?

道歉,如果互联网上已有答案。尽管进行了一周的搜索/试验,我还是无法解决这个问题。

1 个答案:

答案 0 :(得分:4)

初始化控制器时,您只能排序一次:

sortedItems: Ember.computed(function() {
    return Ember.get(this, 'model.items').sortBy('sortOrder');
})

因为您正在使用计算的排序属性,所以只要sortOrder属性在任何项目上发生更改,它就会尝试为您排序列表,这会重新渲染#each并做一些时髦的事情。

最初使用上面的方法排序,然后让jQuery处理项目的顺序 - 而不是jQuery和Ember。