Ember.js从动态路线过滤数据

bit*_*yan 4 javascript ember.js

我正在尝试使用动态路由基于搜索字符串过滤数据.当使用transitionToRoute来自控制器的函数时,路径中的模型数据会正确地返回到视图,但是当直接导航到URL或刷新页面时,所有forEach调用都没有被执行,因为模型中的数据长度为0 .

我有一种感觉,这是因为数据是异步加载的,但是我不知道如何延迟forEach循环和视图的呈现,直到你find的promise得到解决并且forEach循环完成.

这是model我的路由器的功能:

model : function( params ){
    var lists = App.List.find( ), //gets all the lists
        query = params.query, //query string from url
        re = new RegExp( query, 'i' );

    this.set( 'query', query );

    return lists.forEach( function( list ){
        var cards = list.get( 'cards' ).forEach( function( card ){

            //the view has a class bound to the hide property of each card
            card.set( 'hide',
                ( query.length ) ? !( re.test( card.get( 'description' ) ) ) : false
            );
        } );

        return list;
    });
}
Run Code Online (Sandbox Code Playgroud)

当用户使用带有查询字符串的url命中应用程序时,#/search/red我只想要返回其中包含"red"的卡片.

mav*_*ein 7

我刚刚重新发现了这个问题,这是我尝试给出一个答案.正如我在评论中已经提到的,这是我的基本想法:

使用计算属性:

  • 不要在模型钩子中进行过滤,只需返回列表.
  • 在Route的控制器上设置查询(名为SearchController?)
  • 将控制器中的过滤作为计算属性进行

与观察者:(更接近您的原始代码)

  • 不要在模型钩子中进行过滤,只需返回列表.
  • 在Route的控制器上设置查询(名为SearchController?)
  • 采用逻辑从模型钩子中隐藏卡片并将其作为Controller上的观察者实现

最好的方法是使用计算属性,但我不知道如何去做(Ember团队声明计算属性通常会导致更好的代码).因此,这是使用Observer方法的代码的粗略草图.这应该可以作为一个开始:

路线:

model : function( params ){
    this.set( 'query', params.query );
    return App.List.find(); //gets all the lists
},
setupController : function(controller, model) {
    this._super(controller, model);
    // setupController is a good location to setup your controller
    controller.set("query", this.get("query"));
}
Run Code Online (Sandbox Code Playgroud)

控制器:

App.SearchController = Ember.ArrayController.extend({
    query : '',
    // this observer will fire:
    // 1.: every time a list object is added or removed from the underlying array
    // 2.: the query changes
    modelAndQueryObserver : function(){
            re = new RegExp( this.get("query"), 'i' );
        return this.get("model").forEach( function( list ){
            var cards = list.get( 'cards' ).forEach( function( card ){
            //the view has a class bound to the hide property of each card
            card.set( 'hide',
                    ( query.length ) ? !( re.test( card.get( 'description' ) ) ) : false
                );
            } );

            return list;
        });
    }.observes("model.@each", "query")
});
Run Code Online (Sandbox Code Playgroud)