设置“sortAscending”时,ArrayController的“arrangeContent”并不总是更新

时间:2014-01-28 17:22:53

标签: ember.js

我正在尝试使用一个HTML select标记在我的Ember.ArrayController子类中设置动态排序,如下所示:

App.ListController = Ember.ArrayController.extend
    sortOptions: [{id: 0, text: 'Price High-Low', sortBy: 'pricing', sortAsc: false},
              {id: 1, text: 'Price Low-High', sortBy: 'pricing', sortAsc: true},
              {id: 2, text: 'Name Ascending', sortBy: 'name', sortAsc: true},
              {id: 3, text: 'Name Descending', sortBy: 'name', sortAsc: false}]
    currentSortOptionId: 0

    sortBy: (->
        this.get('sortOptions')[this.get('currentSortOptionId')].sortBy
    ).property('currentSortOptionId')

    # Override
    sortProperties: (->
        [this.get('sortBy')]
    ).property('sortBy')

    # Override
    sortAscending: (->
        this.get('sortOptions')[this.get('currentSortOptionId')].sortAsc
    ).property('currentSortOptionId')

在我的模板中,我有:

Sort by {{view Ember.Select content=sortOptions
                                    optionValuePath="content.id"
                                    optionLabelPath="content.text"
                                    value=currentSortOptionId}}

{{#each listing in controller.arrangeContent}}
    ...
{{/each}}

更改选择器大部分时间都有效,而始终可用于切换sort属性。但是,排序方向(通过“sortAscending”)属性会混淆,并且似乎有时会抛出一个操作(即使用先前为“sortAscending”选择的值)。

这可能会发生什么?

编辑:这是一个孤立的例子的JSFiddle:http://jsfiddle.net/s9AFr/3/

如果您多次更改排序选择器,您可以说服自己在某些时候错误地排序 ,尤其是在排序的升序/降序功能时。这种情况似乎“滞后”了用户的选择。

1 个答案:

答案 0 :(得分:3)

不幸的是,我认为这是由于bug

为什么会发生

基本上现在发生的事情是Ember不希望sortProperties和sortAscending同时改变。在SortableMixin的sortAscendingWillChange观察者中,我们跟踪sortAscending的旧值(将其存储在_lastSortAscending中),然后,在后观察者中,如果sortAscending确实如此,他们只是flip the arrangedContent array

sortAscendingDidChange: Ember.observer('sortAscending', function() {
  if (get(this, 'sortAscending') !== this._lastSortAscending) {
    var arrangedContent = get(this, 'arrangedContent');
    arrangedContent.reverseObjects();
  }
}),

当您同时设置sortAscendingsortProperties时会出现问题,因为在观察者触发之前sortAscendingWillChange,保留OLD sortAscending属性的机架,然后因为{{1} }更改后,数组将使用sortProperties的NEW值进行重新排序(所以此时,所有内容都按照您的预期排序)....但最后sortAscending观察者会触发,看到sortAscending不同,所以它再次翻转整个数组。

编辑:解决(JSfiddle

鉴于此错误的原因,我认为解决方法是确保sortAscendingDidChangesortAscending不会同时更改。

因此,我们可以在观察sortProperties的观察者中设置它,而不是使sortAscending成为计算属性,而是在下一个运行循环中设置它(因此我们使用currentSortOptionId )。这样,Ember.run.later计算属性将首先更改,内容将被排序,然后sortProperties属性将被设置。