骨干过滤集合

时间:2014-10-29 15:14:31

标签: javascript backbone.js backbone-collections

我正在尝试根据名为status的属性过滤集合。过滤后,我想重新渲染视图以反映过滤后的结果。到目前为止,我已经在我的收藏中提出了这个功能。

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()函数一旦过滤器完成,但没有继续重置集合?

2 个答案:

答案 0 :(得分: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)
        });
    },
});

答案 1 :(得分:0)

您必须为集合的模型(app.Project)添加额外的属性,该模型将存储指示项目是否必须显示的标志。

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

然后你必须将代码添加到模型View render中,它会根据display属性的值显示/隐藏View元素:

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

最后,您必须修改ProjectCollection的{​​{1}}方法,以便在每个模型上设置status属性:

display