Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling view function from another view - Backbone

Tags:

backbone.js

I have the following views in my application. Basically I want to call show_house() in App.MapView when the li of the App.HouseListElemView is clicked.

What would be the best way of doing this?

App.HouseListElemView = Backbone.View.extend({
    tagName: 'li',
    events: {
        'click': function() {
            // call show_house in App.MapView
        }
    },
    initialize: function() {
        this.template = _.template($('#house-list-template').html());
        this.render();
    },
    render: function() {
        var html = this.template({model: this.model.toJSON()});
        $(this.el).append(html);
    },   
});

App.MapView = Backbone.View.extend({
   el: '.map',
   events: {
       'list_house_click': 'show_house',
   },
   initialize: function() {
       this.map = new GMaps({
           div: this.el,
           lat: -12.043333,
           lng: -77.028333,   
       });
       App.houseCollection.bind('reset', this.populate_markers, this);
   },
   populate_markers: function(collection) {
       _.each(collection.models, function(house) {
            var html = 'hello'
            this.map.addMarker({
                lat: house.attributes.lat,
                lng: house.attributes.lng,
                infoWindow: {
                    content: html,
                }                
            });
       }, this);
   },
   show_house: function() {
       console.log('show house');
   }
});
like image 912
AlexBrand Avatar asked Jun 14 '12 23:06

AlexBrand


1 Answers

The current house is really part of your application's global state so create a new model to hold your global application state:

var AppState  = Backbone.Model.extend({ /* maybe something in here, maybe not */ });
var app_state = new AppState;

Then your HouseListElemView can respond to clicks by setting a value in app_state:

App.HouseListElemView = Backbone.View.extend({
    //...
    events: {
        'click': 'set_current_house'
    },
    set_current_house: function() {
        // Presumably this view has a model that is the house in question...
        app_state.set('current_house', this.model.id);
    },
    //...
});

and then your MapView simply listens for 'change:current_house' events from app_state:

App.MapView = Backbone.View.extend({
    //...
    initialize: function() {
        _.bindAll(this, 'show_house');
        app_state.on('change:current_house', this.show_house);
    },
    show_house: function(m) {
        // 'm' is actually 'app_state' here so...
        console.log('Current house is now ', m.get('current_house'));
    },
    //...
});

Demo: http://jsfiddle.net/ambiguous/sXFLC/1/

You might want current_house to be an actual model rather than simply the id of course but that's easy.

You'll probably be able to find all sorts of other uses for app_state once you have it. You can even add a little bit of REST and AJAX and get persistence for your application settings pretty much for free.

Events are the usual solution to every problem in Backbone and you can make models for anything you want, you can even make temporary models strictly for gluing things together.

like image 189
mu is too short Avatar answered Oct 23 '22 05:10

mu is too short