0

I am having problems triggering an event on the initialization of a view. If I use setTimeout to call the event, the event is fired. However the event is not fire on the view's initialization.

/*global app */

define([
    'handlebars',
    'text!templates/achievements.html'
], function (Handlebars, AchievementsTemplate) {
"use strict";
var AchievementsView = Backbone.View.extend({

    achievementsTemplate: Handlebars.compile(AchievementsTemplate),

    initialize: function () {
        var el = this.render(this.model);
        this.$weekFilter = $(el).find(".challenge-nav li.open a");
        this.model.bind('change', this.resetFilters, this);
        this.resetFilters();
    },
    render: function (model) {
        this.$el.html(this.achievementsTemplate(model.toJSON()));
        return this.$el;
    },
    events: {
        "click .challenge-nav li a": "filterAchievements"
    },
    resetFilters: function () {
        this.$weekFilter.first().trigger("click");
    },
    filterAchievements: function (ev) {
        console.log("test");
    }
});
return AchievementsView;
});

The above does not call the resetFilters function, but if I do a setTimeout, the function is called. Only guess is that the events are bound very late? Any Idea?

Hi All,

/*global app */

define([
    'handlebars',
    'text!templates/achievements.html'
], function (Handlebars, AchievementsTemplate) {
"use strict";
var AchievementsView = Backbone.View.extend({

    achievementsTemplate: Handlebars.compile(AchievementsTemplate),

    initialize: function () {
        var el = this.render(this.model);
        this.$weekFilter = $(el).find(".challenge-nav li.open a");
        this.model.bind('change', this.resetFilters, this);
        this.resetFilters();
    },
    render: function (model) {
        this.$el.html(this.achievementsTemplate(model.toJSON()));
        return this.$el;
    },
    events: {
        "click .challenge-nav li a": "filterAchievements"
    },
    resetFilters: function () {
        var self = this;
        setTimeout(function () {
            self.$weekFilter.first().trigger("click");
        },100);
    },
    filterAchievements: function (ev) {
        console.log("test");
    }
});
return AchievementsView;
});
TYRONEMICHAEL
  • 4,174
  • 4
  • 30
  • 47
  • Are you sure the `resetFilters` is not been called?, try to add a `console.log` into it. I'm guessing the problem is that the `this.$weekFilter` DOM element is not completely full filled in the moment the method is called. – fguillen Jul 24 '12 at 12:34
  • Ya this.resetFilters() is definitely being called. Console.logged it. The issue is that when I trigger the click event, the filterAchievements is not being called. Even console.logged(this.$weekFilter) to see if it was loaded into the DOM, and it sure was. – TYRONEMICHAEL Jul 24 '12 at 12:37
  • I still think the problem is that `this.$weekFilter` is not loaded when `self.$weekFilter.first().trigger("click");` is called. [Whatever console.log sais](http://stackoverflow.com/questions/9911637/backbone-js-model-get-returning-undefined-even-though-i-can-see-the-attribut/9912865#9912865), try `console.log( self.$weekFilter.first() )` just before `self.$weekFilter.first().trigger("click");`. – fguillen Jul 24 '12 at 13:04
  • Will definitely do. Will work on it tonight and revert. – TYRONEMICHAEL Jul 24 '12 at 13:20

1 Answers1

2

If the $weekFilter DOM element is not part of the Achievements template, so it is in the DOM when you initialize the widget, then the problem is that all events are delegated after the initialization. See backbone's source: http://backbonejs.org/docs/backbone.html#section-145.

Why don't you move this.resetFilters() to render()?

Georgii Ivankin
  • 2,702
  • 2
  • 23
  • 35