1
votes

I'm new to backbone.js and trying to understand how routes, views etc works and now I have a problem with events building up for the same view. here is a clip that will show you exactly what I mean. http://screencast.com/t/QIGNpeT2OUWu

This is how my backbone router looks like

var Router = Backbone.Router.extend({

    routes: {
        "pages": "pages",
    }
    pages: function () {
        var page_view = new PageView();
    }
});

So when I click the Pages link I create a new PageView and this is the code I'm using

PageView = Backbone.View.extend({
    el: $("#content"),
    initialize: function () {
        $.ajax({
            url: '/pages',
            success: function (data) {
                $("#content").html(data);
            }
        });
    },
    events: {
        "click td input[type=checkbox]": "updatePublishedStatus"
    },
    updatePublishedStatus: function (event) {
        console.log('update publish status');
    }
});

pretty basic I guess but as you can see in the clip each time I navigate to /pages I get another event registered to the checkbox.

2

2 Answers

2
votes

There are a few things going wrong here.

  1. Your video indicates pages being a collection well, Pages. Pages being a Backbone.Model with attributes such as Page name, slug, published etc... You lack that and it's going to hurt. You shouldn't just load some html and push it to your DOM, this defies the whole purpose of using Backbone in the first place.
  2. If you do create a Model for a Page it will have a View. Then your /pages route will show the view of the Collection Pages etc.
  3. You will fetch your data not inside a view's initialize but rather by doing pages.fetch(); where pages is an instance of the Pages collection. This can happen before you even initialize your router.
  4. When changing attributes through your view, the individual models will be updated.

As a sidepoint: Fetching data on initialize is not great. You can call render() before you actually get the data and that's no fun. Also instead of doing $('#content') you can use the view's $el. As in this.$el.html(...);

1
votes

Move var page_view = new PageView() to be outside of Router.pages().

Have the PageView.initialize() success callback save data to a variable. Either in PageView or in a model.

Add a render function to PageView that sets $("#content").html(data);.

Call page_view.render() within Router.pages().