Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js - Correct way of filtering and displaying collection data in a view

Tags:

backbone.js

I have got a huge list of tasks loaded on the start.
I want to show them depending on selected list / inbox, so that there won't be additional loadings for each list.

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) );     } }); 

This code works, but the reset() function removes other tasks in actual list from tasks collection. And on another route, tasks collection is empty.

Is there any reasonable way to achieve this? thanks for any idea.

ps: backbone novice


UPDATE

Thx to @sled and @ibjhb for comments, here is snippet of working solution.

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) );     } }); 
like image 212
Juraj Ivan Avatar asked Jul 28 '11 20:07

Juraj Ivan


People also ask

Which of the following is the correct syntax for creating backbone collection with model model?

The Backbone. js collection models specify the array or models which are created inside of a collection. Syntax: collection.

What is a backbone view?

The Backbone. js Views specify how your data looks like. They represent model's data to the users. They can be used with any JavaScript template library. They handle users input events, bind events and methods, render model and collection and interact with users.

How does Backbone JS work?

Backbone. js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.

What is El property of backbone JS view?

The Backbone. js View el method defines the element that is used as the view reference. this. el is created from the view's tagName, className, id and attributes properties, if specified.


2 Answers

I think you need to use another collection. For example, in your inbox, do this:

inbox: function(){     currentCollection = new TasksCollection(tasks.inbox()); } 

I haven't tested this but when you do a .reset(); you are removing all your models and loading the ones passed in.

like image 115
James Brown Avatar answered Oct 11 '22 16:10

James Brown


@sled there's typos in the code you posted, see comments inline. Did you post this as a project somewhere?

// 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; }, 
like image 32
bazzargh Avatar answered Oct 11 '22 15:10

bazzargh