Michael Joseph Aubry
Michael Joseph Aubry

Reputation: 13452

Backbone pass specific models in the collection to view?

var theseMessages = window.App.data.messages.where({ chat_id: 2 })
this.messagesView = new MessagesView({ collection: theseMessages });

I am not sure the proper way to pass in to the view constructor the collection that has a specific property.

Example my collection may look like

[
  {
    "chat_id": "1",
    "facebook_name": "Tim Parker",
    "facebook_email": "[email protected]",
    "facebook_id": "1663565265",
    "gravatar": null,
    "message": "Whats up",
    "_id": "533b6a4c7cc6647012f441ad",
    "__v": 0,
    "sent": "2014-04-02T01:39:24.747Z"
  },
  {
    "chat_id": "2",
    "facebook_name": "nick matthews",
    "facebook_email": "[email protected]",
    "facebook_id": "1663565265",
    "gravatar": null,
    "message": "Hey admin",
    "_id": "434636",
    "__v": 0,
    "sent": "2014-04-02T01:48:45.585Z"
  }
]

So when I want to render this collection in my app and only pass the models that have chat_id : 2 I would think something like this is sufficient?

var theseMessages = window.App.data.messages.where({ chat_id: 2 })
this.messagesView = new MessagesView({ collection: theseMessages });

But it gives me an error any ideas?

Edit: Should have been more specific from the get go, I am using a marionette collection view. So I need to pass a collection, but there has to be a way to limit the collection to items with specific attributes, maybe I need to change my logic?

var Marionette = require('backbone.marionette');

var MessageView = Marionette.ItemView.extend({

    className: 'message row',
    template: require('../../templates/message.hbs')

});

module.exports = CollectionView = Marionette.CollectionView.extend({

    className: 'collection',
    initialize: function() {
        this.listenTo(this.collection, 'change', this.render);
    },
    itemView: MessageView

});

Upvotes: 0

Views: 69

Answers (2)

Mike Stapp
Mike Stapp

Reputation: 626

In your line where you filter the Collection:

var theseMessages = window.App.data.messages.where({ chat_id: 2 })

the variable theseMessages just holds an array of items from the Collection, not another Collection itself -- that's probably why you're getting an error in MessagesView.

I would do the filtering dynamically in either the Collection or in MessagesView itself when rendering, rather than trying to pass an already-filtered Collection to MessagesView's constructor. Most of the time, I'd probably do it in MessageView, since I tend to think of filtering as a view-specific thing. But filtering in the Collection would be fine if that Collection isn't going to be used in another view at the same time.

Either way, here's some example code. To filter in the MessageView:

// within MessageView 
serializeData: function() {
    var data = Marionette.CollectionView.prototype.serializeData.call(this);
    return _.where(data, { chat_id: 2 });
}

Or to filter in your Collection instead:

// within your Collection
toJSON: function() {
    return this.chain()
       .where({ chat_id: 2 })
       .map(function(model){ return model.toJSON(); }
       .value();
}

I haven't tested that code, but something like that should work.

Incidentally, to clarify the collection: vs model: subject that was brought up in other comments here: you are correct in using the collection: option in the view's constructor. Backbone & Marionette want a collection: for a Collection, and a model: for a single Model.

Upvotes: 1

cclerv
cclerv

Reputation: 2969

I think you meant to do this:

this.messagesView = new MessagesView({ model: theseMessages });

Upvotes: 1

Related Questions