2012-06-14 32 views
8

Tengo las siguientes vistas en mi aplicación. Básicamente quiero llamar a show_house() en App.MapView cuando se hace clic en el li de App.HouseListElemView.Llamando a la función vista desde otra vista - Backbone

¿Cuál sería la mejor manera de hacerlo?

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'); 
    } 
}); 

Respuesta

14

La casa actual es realmente parte del estado global de la aplicación para crear un nuevo modelo para mantener su estado de aplicación global:

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

Luego, su HouseListElemView puede responder a clics mediante el establecimiento de un valor en 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); 
    }, 
    //... 
}); 

y luego su MapView simplemente escucha las 'change:current_house' eventos desde 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')); 
    }, 
    //... 
}); 

Demostración: http://jsfiddle.net/ambiguous/sXFLC/1/

Es posible que desee current_house a ser un modelo real en lugar de simplemente el id, por supuesto, pero eso es fácil.

Probablemente pueda encontrar todo tipo de usos diferentes para app_state una vez que lo tiene. Incluso puede agregar un poco de REST y AJAX y obtener persistencia para la configuración de su aplicación prácticamente de forma gratuita.

Los eventos son la solución habitual para todos los problemas en Backbone y puede hacer modelos para todo lo que desee, incluso puede hacer modelos temporales estrictamente para pegar cosas.

+0

hermosa .. gracias – AlexBrand

+0

+1. Disculpe mi ignorancia, pero ¿cuál es la diferencia entre este método/appstate y la extensión [Backbone.Events] (http://lostechies.com/derickbailey/2012/04/03/revisiting-the-backbone-event-aggregator-lessons- aprendido /) para PubSub tradicional? – TYRONEMICHAEL

+1

@TyroneMichael: fácil persistencia en su mayor parte. PubSub solo enruta la información y se olvida de ella, recuerda un modelo y facilita la persistencia del estado en su servidor. –

Cuestiones relacionadas