多次设置sortProperties后,Ember computed.sort失败

时间:2014-07-26 03:52:18

标签: ember.js handlebars.js

我正在尝试将排序+过滤实现到我的阵列控制器中。一切正常,除了我的模板在更改排序方向超过2次后似乎没有得到计算属性。我不确定什么是真的出错或是否是一个错误。

以下是相关代码和failing bin(多次单击排序按钮,模板停止显示项目控制器的计算属性)。

{{#each sortedContent}}
  <li>{{title}} - {{symbol}}{{totalAmount}}</li>
{{/each}}

App.IndexController = Em.ArrayController.extend({

  itemController: 'item',

  filterText: '',

  sortProperties: ['totalAmount:asc'],
  sortedContent: Em.computed.sort('filteredContent', 'sortProperties'),

  filteredContent: function() {
    console.log('filter');
    return this.filter(function(item) {
      return item.get('title').indexOf(this.get('filterText')) >= 0;
    }.bind(this));
  }.property('filterText','@this'),

  actions: {
    sortBy: function() {
      var direction = 'asc';
      if(this.get('sortProperties.0').split(':')[1] === 'asc') {
        direction = 'desc'; 
      }
      console.log('totalAmount:'+direction);
      this.set('sortProperties', ['totalAmount:'+direction]);
    }
  }

});

App.ItemController = Em.ObjectController.extend({
  totalAmount: Em.computed.alias('price.amount'),
  symbol: Em.computed.alias('price.currency')
});

2 个答案:

答案 0 :(得分:4)

我盯着它看了一会儿,但我知道它很小。

您的已排序内容和已过滤的内容都是计算出来的,因此您需要确保他们互相观看更改。如果您将sortProperties绑定到filteredContent,它就会有效。

property('filterText', '@this', 'sortProperties')

使用JSBin:http://emberjs.jsbin.com/bicepobu/1/edit

我意识到这个集合仍然存在,并且当我开始在文本字段中输入过滤器并且它正在渲染时没有抛出任何错误,然后我可以点击两次并再次将其弄错...

计算属性错误几乎相当于旧的“遗忘的分号”。我发誓,我自己的Ember代码中的9/10错误来自于这种情况。

<强>更新::

好的,所以我想我可以更好地描述正在发生的事情。您正在将filteredContent送入宏。该宏正在删除并向过滤的内容数组中添加项目。如果你仔细想想,发生的事情是有道理的。

看一下这一行:https://github.com/emberjs/ember.js/blob/v1.6.1/packages_es6/ember-runtime/lib/computed/reduce_computed_macros.js#L756

return arrayComputed(itemsKey, { //...
  1. 您点击了按钮以运行排序宏。
  2. 排序宏撕开并重建filteredContent返回新集合。这就是filteredContent失去视力的地方!
  3. 当您第二次点击过滤器按钮 时,它正在尝试访问原始的filteredContent,它被撕开并且从未使用新模型进行更新! (因此,需要观察sortedProperties的变化)。它是第一次工作,因为它有一个健康的原始阵列可供使用。第二次,它抓住了“稀薄的空气”(空阵)。
  4. 如果你的自定义过滤器属性没有注意对sortProperties的更改,那么在宏被修改后它不知道重新建立自己。

    糟糕!当然不要反对Ember家伙。

    如果排序宏只返回相同的集合而不是一个全新的集合,那将是很好的...这可能是一个非常好的理由。

答案 1 :(得分:2)

看起来像Ember或其他东西,讨厌你的物品控制器。我的工作猜测/理论是它在某些时候与项目控制器断开连接,然后所有的排序和其他标签都中断(由于它们依赖于项目控制器)

http://emberjs.jsbin.com/jakax/1/edit

我不确定究竟是什么问题,但我可能只是将它包装在普通的Ember对象中(取决于你想要做的事情)。

App.Foo = Em.Object.extend({
  totalAmount: Em.computed.alias('price.amount'),
  symbol: Em.computed.alias('price.currency')
});

http://emberjs.jsbin.com/jakax/2/edit