chriskvik
chriskvik

Reputation: 1281

Passing context of view on event in backbone.js

I have a context problem / design problem for my Backbone view.

Goal

  1. The user selects a user from a list / user collection in a separate view.

  2. The mentioned view passes an global event that the editUserView receives ("edit-contact").

  3. The editUserView should receive this event and extract the (user) model.id attribute. By using this model.id I want to update the view with the corresponding object retrieved from the existing view model Tsms.Collection.Users.

Problem

The context passed to the updateView function is wrong, and thus I do not have access to the parent views .render() function. The debugger states "render() is not a function".

Since the context is not that of the parent view I am also unable to set the this.current variable.

How would I go about solving this problem?

View code

Tsms.Views.editUserView = Backbone.View.extend({
    model: Tsms.Collections.Users,
    initialize: function(options) {
        Tsms.require_template('edituser')
        this.template = _.template($('#template_edituser').html());
        this.current = -1;

        Tsms.vent.on('edit-contact', this.updateView)
    },
    updateView: function(model) {
        this.current = model.id;
        this.render();
    },
    render: function() {
        this.$el.html(this.template(this.model.get(this.current).attributes));
        return this;
    }
});

Upvotes: 0

Views: 1237

Answers (2)

Emile Bergeron
Emile Bergeron

Reputation: 17430

While mu is too short is right, you should use Backbone's listenTo to avoid memory leaks (zombie views).

this.listenTo(Tsms.vent, 'edit-contact', this.updateView);

The context is automatically set to this, the calling view.

When remove is called on the view, stopListening is called and any references kept for events are removed.

Another reason to avoid on is that it should be the view that is responsible for the events it wants to handle, the event bus shouldn't have to know.

Upvotes: 0

mu is too short
mu is too short

Reputation: 434665

Backbone's on actually takes three arguments:

on object.on(event, callback, [context])
[...]

To supply a context value for this when the callback is invoked, pass the optional last argument: model.on('change', this.render, this) or model.on({change: this.render}, this).

The easiest and (currently) most idiomatic way to solve your problem would be to use the third context argument:

Tsms.vent.on('edit-contact', this.updateView, this);

Upvotes: 1

Related Questions