【问题标题】:Ember.js: Trigger 'Ember.computed.filter' to update when a property changes in the controllerEmber.js:触发“Ember.computed.filter”以在控制器中的属性更改时进行更新
【发布时间】:2014-05-04 11:34:09
【问题描述】:

我正在尝试根据来自文本输入的输入使用Ember.computed.filter 过滤 ArrayController 的内容。

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 的值发生更改时更新(即,任何时候有人输入文本输入)。现在的问题是,它仅在模型本身发生更改或控制器首次加载时才会更新。

searchFilter 更新时,是否有触发Ember.computed.filter 更新?我正在使用Ember.computed.filter,因为它似乎比普通的计算属性更有效,我相信每次都会重新创建整个数组(如果我弄错了,请告诉我)。此外,Ember.compute.filter 简单易用且非常干净!

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

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

感谢您的时间和任何帮助。

【问题讨论】:

    标签: ember.js


    【解决方案1】:

    也许太简单了,但是 Ember.computed.filter 支持使用 .property() 的依赖键,所以这会很好:

    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:http://emberjs.jsbin.com/tefes/1/edit

    【讨论】:

    • 一点也不简单!这正是我所希望的。我想我什至在某个时候尝试过它,但一定是把语法弄错了一点。也感谢 JSBin。确认它应该工作总是有用的=)
    • 很高兴我能帮上忙。棘手的部分是,如果您只添加“searchFilter”作为依赖键,它就不起作用。可能是因为它以某种方式覆盖了由 computed.filter() 的第一个参数提供的所需的“模型”依赖键。但这只是一个猜测,我仍然需要了解很多关于 ember 的内部结构。
    • @BavoVanGeit 一旦searchFilter 改变,整个数组是否应该重新渲染?我的印象是Ember.computed.filer 通过在同一个数组中添加/删除项目来避免这种情况,但是当我检查 DOM 并监控你的 jsbin 中的单个 li 时,它们似乎都被重新渲染了时间。
    • 我一直认为所有li 都需要重新渲染。在模板中,使用了一个普通的 each ,它只是注意到过滤的人被改变了,因此 {{each}} 被重新渲染。
    【解决方案2】:

    我不确定您将如何使用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('content.@each', 'searchFilter')
    

    现在,每当content 数组中的某些内容发生更改或searchFilter 更改值时,都会重新计算filteredPeople

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

    【讨论】:

    • 我对这个方法唯一关心的是,基于查看 Ember.Array.filter 的源,它只是创建一个全新的数组并将通过过滤条件的新对象推送到它上面。结果,我认为对于较大的数组来说效率很低。我正在为一个包含 100 多个元素的数组实现此功能,并且刷新整个 DOM 可能效果不佳。这就是为什么我试图去 Ember.computed.filter 路由,它在引擎盖下使用 ArrayComputed。
    • 啊,好吧,这改变了事情。我实际上有将 100 多个元素渲染到 DOM 中的经验。我想你知道 ember 性能问题。我们实际上采用了以下解决方案:pagedContent 数组,它只显示filteredContent 数组中的 x 个项目。这允许无限滚动或分页实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-10
    相关资源
    最近更新 更多