2014-10-29 138 views
-1

我想根据称为状态的属性筛选集合。一旦过滤,我想重新渲染视图以反映过滤结果。到目前为止,我已经在我的收藏中提出了这个功能。骨干筛选集合

var ProjectCollection = Backbone.Collection.extend({ 

    url: '/projects', 
    model: app.Project, 

    status: function(status) { 
     return this.filter(function(project){ 
      return project.get('status') == status; 
     }); 
    }, 
}); 

在我看来我的运行下面,

filterStatus: function(e) { 
    e.preventDefault(); 

    var elm = $(e.currentTarget), 
     status = elm.data('statusid'); 


    this.collection.reset(this.collection.status(status)); 

} 

渲染以下功能与它也被调用函数一起,

render: function() { 
    this.$el.empty(); 

    console.log("ProjectDashboardView render"); 

    if(this.collection.length < 1) { 
     var noProjects = new app.noProjectsDashboard; 
    } else { 

     this.addAll(); 
    } 

    $(".month-column").height($(".project-holder").height() + 50); 
}, 

addAll: function() { 
    console.log("allAdd"); 
    this.collection.each(function(model){ 
     this.addOne(model) 
    }, this); 
}, 

addOne: function(model) { 
    var view = new app.ProjectTimelineEntry({ 
     model: model 
    }); 

    this.$el.append(view.render()); 

    var number_of_days_in_calendar = 0; 

    $('.month-column').each(function(){ 
     number_of_days_in_calendar = number_of_days_in_calendar + parseInt($(this).data('days')); 
    }); 

    var day_width = 1/(number_of_days_in_calendar) * 100; 


    //Is the start after the end of Feb? 
    var start_date = new Date(model.get('start_date')); 
    var march_date = new Date("03/01/2014"); 

    var current_month = start_date.getMonth() + 1; 
    var march_month = march_date.getMonth() + 1; 
    console.log(current_month, march_month); 
    if(current_month <= march_month) { 
     var start_date_offset = model.get('num_days_from_year_start') * day_width; 
     var duration_of_project = model.get('run_number_days') * day_width; 
     //view.$('.duration-bar').css("background-color", model.get('color')); 
     view.$el.find('.duration-bar').css({ 
      width : duration_of_project + "%", 
      "margin-left" : start_date_offset + "%" 
     }, 500); 
    } else { 
     var start_date_offset = (model.get('num_days_from_year_start') + 2) * day_width; 
     var duration_of_project = model.get('run_number_days') * day_width; 
     //view.$('.duration-bar').css("background-color", model.get('color')); 
     view.$el.find('.duration-bar').css({ 
      width : duration_of_project + "%", 
      "margin-left" : start_date_offset + "%" 
     }, 500); 
    } 

    // if(Date.parse(start_date) < new Date("01/03")) { 
    // console.log("before march"); 
    // } 


}, 

现在这个过滤收集,然而,当我尝试再次过滤集合时,会发生什么情况,它会过滤我刚刚重置的集合,我如何过滤集合,运行视图render()函数o过滤器是否完整,但不会重置收集?

+0

您还可以发布视图的呈现方法吗? – ncksllvn 2014-10-29 15:26:26

+1

您必须为集合的模型('app.Project')添加额外的属性,该属性将存储指示是否需要显示项目的状态。 – hindmost 2014-10-29 15:27:39

+0

@ncksllvn请看我的编辑 – Udders 2014-10-29 15:29:32

回答

1

正如最后提到的,您应该添加一个visible字段到app.Project模型。 然后在ProjectView附加一个侦听这个领域:

this.listenTo(this.model, "change:visible", this.onVisibleChange) 

和方法定义:

onVisibleChange: function(){ 
    $(this.el).css('display', (this.get('visible')) ? 'block': 'none') 
} 

在您的过滤方法,你跑过来集合,并相应地改变每个模型的visible领域,如果它应该或不应该被渲染。

var ProjectCollection = Backbone.Collection.extend({ 

    url: '/projects', 
    model: app.Project, 

    status: function(status) { 
     return this.each(function(project){ 
      project.set('visible', project.get('status') == status) 
     }); 
    }, 
}); 
0

你有额外的属性添加到集合的模型(app.Project)将存储标志,指示,如果一个项目有显示或不。

var app.Project = Backbone.Model.extend({ 
    defaults: { 
     ... 
     status: '', 
     display: true 
    } 
}; 

然后,你必须添加代码到模型视图的render将显示/隐藏查看的元素取决于display属性的值:

var ProjectView = Backbone.View.extend({ 
    ... 
    render: function() { 
     ... 
     if (this.model.get('display')) 
      this.$el.show(); 
     else 
      this.$el.hide(); 
     ... 
     return this; 
    }, 
    ... 
}; 

而且,最后你必须修改ProjectCollectionstatus方法在每个模型上设置display属性:

var ProjectCollection = Backbone.Collection.extend({ 
    url: '/projects', 
    model: app.Project, 

    status: function(status) { 
     this.each(function(project){ 
      project.set('display', project.get('status') == status); 
     }); 
    }, 
    ... 
});