使用jQuery可排序的Ember组件模板问题

时间:2016-05-08 08:18:19

标签: javascript jquery jquery-ui ember.js

我试图创建一个包装jQuery UI Sortable插件的简单Ember组件。不幸的是,当取消sortable并手动更新模型时,组件的模板存在问题。看起来DOM并不反映模型的状态。我找不到原因。

我已创建JS Bin来介绍此问题。更改项目位置时,应删除组中的第一个。不幸的是,它是随机的。

此代码有什么问题?

1 个答案:

答案 0 :(得分:0)

这是您的JS Bin可排序组件:

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

然后这是你的JS Bin updated,代码从ember-ui-sortable repo到以下:

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

正如您所看到的那样,与原作相比还有更多的内容,所以您可以查看您错过的内容,希望这对您有所帮助。 通过ember-cli安装组件插件可能是一个好主意,但也可以先使用ember-sortable之类的方法查看ember-observer之类的竞争解决方案。