1

Below is my backbone view.

define([
    'app',
    'backbone',
    'twig',
    'templates/report',
    'data/reportViewCollection',
    'data/reportViewModel'
], function (app, Backbone, Twig, template, Collection, Model) {

    var collection = new Collection();
    var fetching;

    return Backbone.View.extend({
        setParams: function (rlId, viewId, categoryId, depth) {
            // reset any possible pending previous repests.
            fetching = false;

            var model = collection.getModel(rlId, viewId, categoryId, depth);
            if (!model) {
                model = new Model({
                    rlId: rlId,
                    viewId: viewId,
                    categoryId: categoryId,
                    depth: depth
                });
                fetching = model.fetch({
                    success: function (model) {
                        collection.add(model);
                    },
                    error: function (model) {
                        alert('error getting report view');
                    }
                });
            }
            this.model = model;
        },
        render: function () {
            var that = this;
            var done = function() {
                app.vent.trigger('domchange:title', that.model.get('title'));
                that.$el.html(Twig.render(template, that.model.toJSON()));

                that.delegateEvents(that.events);
                fetching = false;
            };
            if (fetching) {
                app.loading(this);
                fetching.done(done);
            } else {
                done();
            }
            return this;
        },
        events: {
            'change select.view-select': 'viewSelect',
            'click #dothing': function (e) {e.preventDefault(); alert('hi');}
        },
        viewSelect: function(e) {
            var selectedView = $(e.target).val();
            var rlId = this.model.get('rlId');
            if (!rlId) rlId = 0;
            var url = 'report/' + rlId + '/' + selectedView;
            console.log(this, e, url);
            Backbone.history.navigate(url, {trigger: true});
        }
    });
});

Description of functionality:

What happens is when a specific url is navigated to, the setParams() function is called to fetch the model from the server. When the render method is called, it checks if we are currently fetching the model and if so, uses sets a deferred callback to render the template when it gets done fetching. When the model is fetch-ed and we are ready to render, renders the template and fills in the view by that.$el.html().

Problem:

What happens is that my events work perfectly the first time I navigate to a url, but when I hit the back button, my events don't get attached.

I've stepped through the code and can't see any differences. The only real difference is that I'm loading the model from the cached collection immediately instead of doing an ajax request to fetch it.

Any clues what is going on?

Icode4food
  • 8,504
  • 16
  • 61
  • 93

2 Answers2

0

try to change:

that.$el.html(Twig.render(template, that.model.toJSON()));

to

that.$el.html("");
that.$el.append(Twig.render(template, that.model.toJSON()));

had kind the same problem and this fixed it.

Saligor
  • 78
  • 5
0

I resolved my issue. The comment by @mu set me in the right direction.

I am using Marionette and my view is contained in a region. In the Region's open function, it is doing this.$el.html(view.el); which wipes out the events in certain circumstances. I'm still not sure why it does in some but on in others.

The Solution proved to be to add an onShow function to my view that call's this.delegateEvents(). Everything is working smoothly now!

I eventually figured it out by stepping through the code and watching the events registered on the view's div.

Icode4food
  • 8,504
  • 16
  • 61
  • 93