首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Backbone.js -在视图中筛选和显示收集数据的正确方法

Backbone.js -在视图中筛选和显示收集数据的正确方法
EN

Stack Overflow用户
提问于 2011-07-28 20:20:35
回答 3查看 32.8K关注 0票数 39

我有一个巨大的清单的任务加载在开始。

我希望根据选定的列表/收件箱显示它们,这样每个列表就不会有额外的加载。

代码语言:javascript
运行
复制
window.Task = Backbone.Model.extend({});

window.TasksCollection = Backbone.Collection.extend({
    model: Task,
    url: '/api/tasks',
    inbox: function() {
        return this.filter(function(task) {
            return task.get('list') == null;
        });
    },
    list: function(id) {
        return this.filter(function(task) {
            return task.get('list') == id;
        });
    }
});

window.tasks = new TasksCollection;

window.TaskView = Backbone.View.extend({
    tagName: 'li',
    template: _.template($('#item-template').html()),
    initialize: function() {
        _.bindAll(this, 'render', 'close');
        this.model.bind('change', this.render);
        this.model.view = this;
    },
    render: function() {
        $(this.el).html(this.template(this.model.toJSON()));
        this.setContent();
        return this;
    },
});

window.TasksView = Backbone.View.extend({
    el: '#todo-list',
    collection: tasks,
    initialize: function() {
        _.bindAll(this, 'render');
        this.collection.bind('reset', this.render);
        this.collection.fetch();
    },
    render: function() {
        var t = this;
        $(t.el).html('');
        this.collection.each(function(task) {
            var view = new TaskView({ model:task });
            $(t.el).append( view.render().el );
        });
        return this;
    },
});

window.Nicetask = Backbone.Router.extend({
    routes: {
        '':             'inbox',
        '/inbox':       'inbox',
        '/list/:id':    'list',
    },
    initialize: function() {
        _.bindAll(this, 'inbox', 'list');
        window.tasksView = new TasksView;
    },
    inbox: function() {
        tasks.reset( tasks.inbox() );
    },
    list: function(id) {
        tasks.reset( tasks.list(id) );
    }
});

此代码可以工作,但reset()函数将实际列表中的其他任务从任务集合中删除。在另一条路径上,任务集合为空。

是否有合理的方法来达到这个目标呢?谢谢你的任何想法。

私人秘书:骨干新手

更新

Thx到@sled和@ibjhb是注释,这里是工作解决方案的片段。

代码语言:javascript
运行
复制
window.TasksView = Backbone.View.extend({
    el: '#todo-list',
    collection: Backbone.Collection.extend(),
    initialize: function() {
        _.bindAll(this, 'render', 'addOne', 'addAll');
        this.collection.bind('add', this.addOne);
        this.collection.bind('reset', this.render);
    },
    render: function(data) {
        $(this.el).html('');
        _.each(data, function(task) {
            this.addOne(task);
        }, this);
        return this;
    },
    addOne: function(task) {
        var view = new TaskView({ model:task });
        $(this.el).append( view.render().el );
    },
});

window.Nicetask = Backbone.Router.extend({
    routes: {
        '':             'inbox',
        '/inbox':       'inbox',
        '/today':       'today',
        '/list/:id':    'list',
    },
    initialize: function() {
        _.bindAll(this, 'inbox', 'today');
        window.tasksView = new TasksView;
        window.menuView = new MenuListView;
        tasks.fetch();
    },
    inbox: function() {
        tasksView.render( tasks.inbox() );
    },
    today: function() {
        tasksView.render( tasks.today() );
    },
    list: function(id) {
        tasksView.render( tasks.list(id) );
    }
});
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-28 20:36:33

我觉得你需要再用一套。例如,在收件箱中,执行以下操作:

代码语言:javascript
运行
复制
inbox: function(){
    currentCollection = new TasksCollection(tasks.inbox());
}

我还没有对此进行测试,但是当您执行.reset()时,您正在删除所有模型并加载传入的模型。

票数 4
EN

Stack Overflow用户

发布于 2012-07-28 15:58:55

@sled在你发布的代码中有排字,请参阅评论。你把这个贴在什么地方了吗?

代码语言:javascript
运行
复制
// add models
add: function(models, options) {
  // TYPO: next line was missing, so single models not handled.
  models = _.isArray(models) ? models.slice() : [models];

  var self = this;

  models = _.filter(models, this.filter);

  // return if no models exist
  // TYPO: returned undefined, so was not chainable
  if(models.length == 0) { return this; }

  // actually add the models to the superset
  this.superset.add(models, options);
  return this;
},

// remove models
remove: function(models, options) {
  // TYPO: next line was missing, so single models not handled.
  models = _.isArray(models) ? models.slice() : [models];

  // remove model from superset
  this.superset.remove(_.filter(_.filter(models, function(cm) {
    // TYPO: not 'm != null', causes error to be thrown
    return cm != null;
  }), this.filter), options);
  // TYPO: missing return so not chainable
  return this;
},
票数 4
EN

Stack Overflow用户

发布于 2011-12-07 20:46:36

对您的解决方案进行快速修改,您正在使用

代码语言:javascript
运行
复制
$(this.el).html('');

我的理解是您的视图和相关的事件绑定仍然存在于浏览器内存中,所以理想情况下您需要在TaskView上使用TaskView()来正确清除事件绑定和html。

这是一个略为不同的答案,因为我一直在寻找一个解决类似问题的办法,希望这可能会对其他人有所帮助。

我的问题是:-通过模型的属性过滤一个完整的集合。例如:用户单击“模型”视图,获取(部分)属性列表,选择属性筛选集合,使其仅显示具有相同值的属性。

我采用的方法是从视图中调用集合上的方法,在我的示例中,视图是特定于模型的,因此:

代码语言:javascript
运行
复制
this.model.collection.myFilter(attr,val);

其中attr是与集合关联的模型的属性,然后在筛选器中类似于

代码语言:javascript
运行
复制
myFilter: function(attr, val){
    var groupByAttr = this.groupBy(function(article){
        var res = (val === undefined)? true : (article.get(attr) == val);
        article.set({selected:res});
        return res;
    });
    return groupByAttr;
}

我使用了._groupBy,因为它返回两个可能有用的数组(正/负)。通过设置mode属性"selected",并将其绑定到模型视图中,我可以轻松地切换显示或隐藏视图的类。

if(val ===未定义)是作为一种简单的方法添加的,通过调用相同的方法而不使用值来清除过滤器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6865174

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档