2014-09-18 76 views
4

我意识到有类似这样的几个问题,但没有一个答案似乎解决了我的问题。我的目标是获取language的列表,并对它们进行过滤,以便我的模板可以显示完整列表的子集。从计算属性返回承诺

我开始通过验证我的计算物业工作:

MyController.js

// Works as expected 
languagesFiltered: function() { 
    return this.get('languages'); 
}.property('languages') 

然后我在过滤器中添加的功能,但在这里就是我遇到了麻烦:

MyController.js

languagesFiltered: function() { 
    // console.log shows that languages is actually a promise 
    var languages = this.get('languages'); 

    // all of this returns a promise, but Handlebars can't handle the promise 
    return languages.then(function(languagesArray) { 
     return languagesArray.filter(function(item, index, enumerable) { 
     return item.get('name') !== 'English'; 
     }); 
    }) 
}.property('languages') 

我试图使用Ember.Array.filter方法(http://emberjs.com/api/classes/Ember.ArrayProxy.html#method_filter)。该过滤器似乎工作正常,但现在languagesFiltered返回一个承诺,Handlebars无法处理。

我想最后一个选择:

MyController.js

languagesFiltered: function() { 
    var languages = this.get('languages'); 

    // "return languages;" works 
    // But "return languages.filter" returns an empty array 
    return languages.filter(function(item, index, enumerable) { 
     console.log(item); 
     return true; 
    }); 
}.property('languages') 

而且console.log(item)不会被调用。所以我的问题是:

  • 什么是最好的方式来实现简单的过滤器我后?
  • 这是一个只读的计算属性,但在计算属性中处理异步值的最佳做法是什么?

我使用Ember 1.7.0-beta4,Ember Data 1.0.0-beta10和ember-cli 0.44。我会升级到Ember 1.7.0,但是有一个小错误影响了我们应用程序的另一部分,所以我们要等到1.7.1。感谢您的输入!

回答

17

您可以尝试退回PromiseArray而不仅仅是承诺。

你应该能够做这样的事情..

languagesFiltered: function() { 
    // all of this returns a promise, but Handlebars can't handle the promise 
    var promise = this.get('languages').then(function(languagesArray) { 
     return languagesArray.filter(function(item, index, enumerable) { 
     return item.get('name') !== 'English'; 
     }); 
    }) 

    return DS.PromiseArray.create({ 
     promise: promise 
    }); 

}.property('languages') 
+1

谢谢@tikotzky!您的解决方案完美运作我没有意识到,当我有一组promise时,我实际上可以将它们包装在'DS.PromiseArray'中。 – 2014-09-18 16:55:32

+0

你实际上是在'DS.PromiseArray'中包装一个单一的承诺。它是一个解决数组的单个承诺。如果承诺解决了一个对象,那么你将需要使用'DS.PromiseObject' – tikotzky 2014-09-18 16:58:33

+0

啊,谢谢澄清。有趣的是,我可以直接返回'this.get('languages')',但是'this.get('languages')'的任何操作都必须包含在DS中。PromiseArray'。你能解释一下吗? – 2014-09-18 17:03:16