【问题标题】:backbone filtering a collection主干过滤集合
【发布时间】:2014-10-29 15:14:31
【问题描述】:

我正在尝试根据名为 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() 函数一次过滤器已完成,但不继续重置集合?

【问题讨论】:

  • 你也可以发布你的视图的渲染方法吗?
  • 您必须向集合的模型 (app.Project) 添加额外的属性,该属性将存储指示项目是否必须显示的状态。
  • @ncksllvn 请查看我的编辑
  • @hindmost 你是什么意思?就像在每个模型上添加可见标志一样?这将如何运作?
  • @Udders 是的,你猜对了。详情见我的回答

标签: javascript backbone.js backbone.js-collections


【解决方案1】:

正如最后提到的,您应该在app.Project 模型中添加一个visible 字段。 然后在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)
        });
    },
});

【讨论】:

    【解决方案2】:

    您必须向集合的模型 (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;
        },
        ...
    };
    

    而且,最后你必须修改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);
            });
        },
        ...
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多