Passing arguments to a backbone view

16,412

Solution 1

You should pass attributes in the initialize() function:

initialize: function (attrs) {
    this.options = attrs;
}

So here you would pass the attributes as an object, like so:

new MyView({
  some: "something",
  that: "something else"
})

Now you have the values that you passed in accessible throughout this instance, in this.options

console.log(this.options.some) # "something"
console.log(this.options.that) # "something else"

To pass in a collection, I recommend making one parent view and one subview:

var View;
var Subview;

View = Backbone.View.extend({
    initialize: function() {
        try {
            if (!(this.collection instanceof Backbone.Collection)) {
                throw new typeError("this.collection not instanceof Backbone.Collection")
            }
            this.subViews = [];
            this.collection.forEach(function (model) {
                this.subViews.push(new SubView({model: model}));
            });
        } catch (e) {
            console.error(e)
        }
    },
    render: function() {
        this.subViews.forEach(function (view) {
            this.$el.append(view.render().$el);
        }, this);
        return this;
    }
});

SubView = Backbone.View.extend({
    initialize: function () {
        try {
            if (!(this.model instanceof Backbone.model)) {
                throw new typeError("this.collection not instanceof Backbone.Collection")
            }
        } catch (e) {
            console.error(e);
        }
    },
    render: function () {
        return this;
    }
});

testCollection = new MyCollection();
collectionView = new View({collection: testCollection});
$("body").html(collectionView.render().$el);

You should always handle the Models of a Collection, not just the data of the collection.

Solution 2

You should have a model for your view and access model's properties when rendering the view.

var myModel = new Backbone.Model();

myModel.set("myThings", myThings);
myModel.set("myOtherThings", myOtherThings);

var myView = new ListView({ model: myModel });
Share:
16,412
Surya Subenthiran
Author by

Surya Subenthiran

Updated on June 05, 2022

Comments

  • Surya Subenthiran
    Surya Subenthiran about 2 years

    Just getting started with Backbone. I have a generic view that can render a collection as a list with a title. I'm currently passing the collection and title into the render method, but that seems a bit odd. Is there another way that's more canonical?

    E.g.:

    var ListView = Backbone.View.extend({
        template: _.template([
            "<div>",
            "<% if (title) { %><h2><%= title %></h2> <% } %>",
            "<% if (items.length > 0) { %>",
            "<ul>",
                "<% items.each(function(item) { %>",
                "<%= itemTemplate(item) %>",
                "<% }); %>",
            "</ul>",
            "<% } else { %><p>None.</p><% } %>",
            "</div>"
        ].join('')),
    
        itemTemplate: _.template(
            "<li><%= attributes.name %> (<%= id %>)</li>"
        ),
    
        render: function(items, title) {
            var html = this.template({
                items: items /* a collection */,
                title : title || '',
                itemTemplate: this.itemTemplate
            });
    
            $(this.el).append(html);
        }
    });
    
    var myView = new ListView({ el: $('#target') });
    myView.render(myThings, 'My Things');
    myView.render(otherThings, 'Other Things');