Yury
Yury

Reputation: 928

How to organize a multi-application with backbone?

I use a clean backbone without wrappers or frameworks.

So I create a site to manage by some products. I have two dynamic pages for this:

These pages are separate backbone applications.

In both pages, there is an element displays a product category. Usually it is a drop-down list.

Next, I will describe the approximate structure of my scripts. It is simple.

js
+- models
|  +- Category.js
|  ...
+- collections
|  +- Categories.js
|  ...
+- views
|  +- CategoriesView.js
|  ...

CategoryView.js contains:

App.Views.CategoriesViews = Backbone.View.extend({
    template: _.template($('#tpl-categories').html()),

    events: {
        'change select': 'toggle'
    },

    initialize: function () {
        _.bindAll(this, 'render');

        this.collection.on('reset', this.render);
    },

    render: function () {
        this.$el
            .html(this.template({ collection: this.collection.toJSON() }));

        return this;
    },

    toggle: function () {
        // Some actions here
        var catId = this.$el.children('select').val();
        App.trigger('toggleCategories', catId);
    }

});

Initialization of the view looks like this:

new App.Views.CategoriesViews({
   el: $('#select-box-cats'),
   collection: new App.Collections.Categories
});

Since this element is on both pages (add.php and edit.php) it works well for both of them.

We assume that the name of the template can be set the same on both pages:

<script type="text/template" id="tpl-categories">

Although I think it is not a good practice.

Well, finally my question.

What happens if one of these pages need to add an event handler to the view. For example:

initialize: function () {
    _.bindAll(this, 'render', 'action');

   this.collection.on('reset', this.render);
   this.collection.on('request', this.action);
},

I added an event to request collection. However, this event should not be present on another page.

What to do? To create a separate view file with the changes to the needs of the page? But it violates the principle of DRY and spawns a lot of client code!

Upvotes: 1

Views: 186

Answers (2)

Craig
Craig

Reputation: 691

You can pass options to the view when you create it.

On your edit page:

new App.Views.CategoriesViews({
    el: $('#select-box-cats'),
    collection: new App.Collections.Categories,
    bindRequest: true, // Trigger the request event.
    toggleCategories: true // Toggle the categories in the toggle method.
});

On your add page:

new App.Views.CategoriesViews({
    el: $('#select-box-cats'),
    collection: new App.Collections.Categories,
    bindRequest: false, // Do not trigger the request event.
    toggleCategories: false // Do not toggle categories in the toggle method.
});

And in your view:

initialize: function() {
    _.bindAll(this, 'render', 'action');

    this.collection.on('reset', this.render);

    // this.options is automatically populated with any parameters included 
    // upon creation.
    if (this.options.bindRequest) {
        this.collection.on('request', this.action);
    }
},

toggle: function () {
    // Some actions here
    var catId = this.$el.children('select').val();

    // Options are available from any method in the view.
    if (this.options.toggleCategories) {
        App.trigger('toggleCategories', catId);
    }
}

Upvotes: 1

Sushanth --
Sushanth --

Reputation: 55750

I feel that a view should not have any collection specific logic. The only thing it should be doing is to render the view based on the events fired.

So what I would do in this case is to bind the common event on the SubView

initialize: function () {
    _.bindAll(this, 'render', 'action');

   this.collection.on('reset', this.render);
},

Which is common for both the pages.

And before the view is actually instantiated in its parent view..

AddView

initialize : function() {
    this.collection = new App.Collections.Categories
    this.collection.on('request', this.action);
},
new App.Views.CategoriesViews({
   el: $('#select-box-cats'),
   collection: this.collection
});

Upvotes: 0

Related Questions