2014-05-04 83 views
2

我试图根据来自文本输入的输入使用Ember.computed.filter过滤ArrayController的内容。Ember.js:触发'Ember.computed.filter'来更新控制器中属性更改时

App.IndexController = Ember.ArrayController.extend({ 
     filteredPeople: Ember.computed.filter('model', function(person){ 
      var searchFilter = this.get('searchFilter'); 
      var regex = new RegExp(searchFilter, 'i'); 
      return person.firstName.match(regex); 
     }), 
     // this is bound to the value of a text input helper 
     // I'm just pre-filling the value to show that the filtering does work 
     searchFilter: 'kris' 
}); 

这个工程很棒,并按预期过滤。不过,我希望随时更新searchFilter的值(即任何时候有人输入到文本输入中)。现在的问题是,只有在模型本身发生变化或控制器第一次加载时才会更新。

有无论如何触发Ember.computed.filter更新时searchFilter更新?我使用的是Ember.computed.filter,因为它似乎比普通的计算属性效率更高,我相信每次都会重新创建整个数组(请让我知道我是否错误)。此外,Ember.compute.filter只是易于使用,非常干净!

我用上面的设置创建了一个JSBin。当用户输入文本框时,我想以某种方式触发Ember.computed.filter更新自己。

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

谢谢您的时间和任何援助。

回答

9

也许太容易了,但Ember.computed.filter支持使用.property()依赖键,以便这将正常工作:只http://emberjs.jsbin.com/tefes/1/edit

+0

不太容易!这正是我所希望的。我想我甚至在某个时候尝试过它,但一定已经把这个语法稍微放了下来。谢谢你的JSBin。总是有用,以确认它应该工作=) – Sarus

+1

很高兴我能帮上忙。棘手的部分是,如果你只添加'searchFilter'作为依赖关键,它不起作用。可能是因为它以某种方式覆盖了由computed.filter()的第一个参数提供的所需“模型”依赖关键字。但这只是一个猜测,我仍然需要学习很多关于ember内部的知识。 –

+0

@BavoVanGeit一旦'searchFilter'改变了整个数组应该重新呈现?我的印象是'Ember.computed.filer'通过添加/删除项目到相同的数组来避免这种情况,但是当我检查DOM并监视jsbin中的单个'li'时,他们绝对看起来都是每次重新呈现。 –

0

我不确定您如何使用Ember.computed.filter来做到这一点。 这将是非常容易使用Ember.Array.filter方法和计算的欢迎使用属性来实现:

searchFilter: 'kris', 

filteredPeople : function(){ 
    var content = this.get('content'), 
     searchFilter = this.get('searchFilter'), 
     regex = new RegExp(searchFilter, 'i'); 

    return content.filter(function(person){ 
     return person.get('firstName').match(regex); 
    }); 
}.property('[email protected]', 'searchFilter') 

filteredPeople现在将重新计算,每次有新的变化的content阵列中或当searchFilter变化值。

JSBin:http://emberjs.jsbin.com/pitefica/6/edit

+0

我:

App.IndexController = Ember.ArrayController.extend({ filteredPeople: Ember.computed.filter('model', function(person){ var searchFilter = this.get('searchFilter'); var regex = new RegExp(searchFilter, 'i'); return person.firstName.match(regex); }).property('model','searchFilter'), searchFilter: 'kris' //this is bound to the value of a text input helper }); 

jsbin这个方法的关注点是基于查看Ember.Array.filter的来源,它只是创建一个全新的数组,并将新对象推送到它上面,从而通过过滤条件。因此,我认为对于较大的阵列来说效率不高。我正在为一个数组实现这个功能,这个数组有100多个元素,刷新整个DOM可能不会很好。这就是为什么我试图去引用使用ArrayComputed的Ember.computed.filter路由。 – Sarus

+0

好的,这改变了事情。我实际上有将100多个元素渲染到DOM中的经验。我觉得你知道这件事上的烬毛性能问题。 我们实际上采用了以下解决方案:一个'pagedContent'数组,它只显示'filteredContent'数组中的x个项目。这允许无限的滚动或分页实现。 –

相关问题