ember.js - EmberJS 计算排序属性与 jQuery UI Sortable 冲突

标签 ember.js jquery-ui-sortable

我在使用 EmberJS 运行拖放排序功能时遇到问题。

涵盖此问题的教程对初始排序没有提供任何帮助,而我是通过计算属性进行的。

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

路线

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
        })
      ]
    });
  }
});

Controller

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

问题

有没有办法避免这种竞争条件或在 Controller 初始化时仅排序一次?

如果互联网上已经有对此问题的答案,我们深表歉意。尽管经过一周的搜索/实验,我仍未能解决这个问题。

最佳答案

Controller 初始化时只能排序一次:

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

因为您使用的是计算排序属性,所以每当任何项目上的 sortOrder 属性发生更改时,它都会尝试对列表进行排序,这会重新呈现 #each 并执行一些有趣的操作。

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

关于ember.js - EmberJS 计算排序属性与 jQuery UI Sortable 冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29219422/

相关文章:

javascript - 通过 hasMany 关系访问 ember-model 对象中的相关集合

jQuery 使用可排序和动态添加元素(实时刷新)

ember.js - 在 {{#linkTo}} 帮助器 <a> 标记上设置自定义数据属性

javascript - 在 Ember 中设置值之前如何检查该值?

javascript - Ember 数据中是否有一个钩子(Hook)我可以用来知道它何时实际向服务器发送请求?

ember.js - 第一次为ember写mocha测试,缺少访问功能

jquery - 如何使用 JQuery 中的 Sortable 对 div 进行水平排序

jquery-ui - jquery ui sortables 连接列表 : copy items

jquery 可排序/可拖动双事件触发

jquery - 能够将 JQuery Sortable(新顺序)保存到 ASP.Net MVC Controller 吗?