2012-06-14 18 views
8

Ich habe die folgenden Ansichten in meiner Anwendung. Grundsätzlich möchte ich show_house() in App.MapView aufrufen, wenn auf die li der App.HouseListElemView geklickt wird.Aufruf der Ansicht-Funktion aus einer anderen Ansicht - Backbone

Was wäre der beste Weg, dies zu tun?

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

Antwort

14

Das aktuelle Haus ist wirklich ein Teil des globalen Zustandes Ihrer Anwendung so ein neues Modell erstellen Sie Ihren globalen Anwendungszustand zu halten:

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

Dann können Sie Ihre HouseListElemView auf Klicks reagieren, indem sie einen Wertes in app_state Einstellung :

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); 
    }, 
    //... 
}); 

und Ihr dann MapView einfach für 'change:current_house' Ereignisse hört von 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/

Vielleicht möchten current_house eher ein tatsächliches Modell sein, als einfach die id natürlich, aber das ist einfach.

Sie werden wahrscheinlich in der Lage sein, alle Arten von anderen Anwendungen für app_state zu finden, sobald Sie es haben. Sie können sogar ein wenig REST und AJAX hinzufügen und erhalten Persistenz für Ihre Anwendung Einstellungen so ziemlich kostenlos.

Ereignisse sind die übliche Lösung für jedes Problem in Backbone und Sie können Modelle für alles, was Sie wollen, machen, können Sie sogar temporäre Modelle ausschließlich zum Zusammenkleben von Dingen.

+0

schön .. danke – AlexBrand

+0

+1. Entschuldige meine Ignoranz, aber was ist der Unterschied zwischen dieser Methode/appstate und der Erweiterung [Backbone.Events] (http://losetechies.com/derickbailey/2012/04/03/revisiting-the-backbone-event-aggregator-lesson- gelernt /) für traditionelle PubSub? – TYRONEMICHAEL

+1

@TyroneMichael: Einfache Persistenz zum größten Teil. PubSub leitet nur Informationen um und vergisst sie, ein Modell merkt sich und macht es einfach, den Zustand auf Ihrem Server zu halten. –

Verwandte Themen