2012-09-13 5 views
16

Ho un numero di modelli di backbone, organizzati in raccolte e connessi alle loro viste e/o raccolte di viste corrispondenti. Alcuni di questi modelli che non appartengono alla stessa collezione devono attivare un evento che interessa un altro modello (e forse più di uno).backbone.js + dispatcher globale degli eventi + require.js: come?

Il modo consigliato per gestire questo è, ritengo, il "dispatcher/aggregatore di eventi globale" come descritto in here e in altri luoghi.

Tuttavia, mi capita anche di usare require.js, che sembra andare contro l'idea di collegare il dispatcher/aggregatore all'oggetto dello spazio dei nomi dell'applicazione - o sbaglio qui?

Quindi la mia domanda è: using require.js come posso avere un numero di diversi modelli di backbone innescare un evento che sarà gestito da un altro modello?

risposta

35

Una soluzione simile a quello che @Andreas p roposed ma senza Backbone.Marionette (fortemente ispirato comunque, see the article linked in the question).

Tutto ciò che dovete fare è definire un modulo che crea un singleton di un listener di eventi e richiede questo oggetto nei moduli in cui si desidera attivare un evento o ascoltare questo evento.

Diciamo che avete app/channel.js che definiscono il canale

define(['backbone', 'underscore'], function (Backbone, _) { 
    var channel = _.extend({}, Backbone.Events); 
    return channel; 
}); 

È quindi possibile utilizzarlo come un ascoltatore via

require(['app/channel'], function (channel) { 
    channel.on('app.event', function() { 
     console.log('app.event'); 
    }); 
}); 

e si può attivare un evento su questo canale via

require(['app/channel'], function (channel) { 
    channel.trigger('app.event'); 
}); 
+0

Penso che questo sia quello che stavo cercando. Grazie mille nikoshr e andreas – alearg

+0

Qual è il vantaggio dell'utilizzo degli eventi in questa situazione? Dobbiamo ancora includere "app/modello" in tutti i moduli in cui genereremo quell'evento. Perché non fare una chiamata API su quel modello? – wizardzloy

+1

@wizardzloy L'unico modulo che devi includere è 'app/channel' dove vuoi ascoltare o attivare un evento globale. 'app/model' è lì solo per dimostrare un utilizzo del campione. – nikoshr

1

Usiamo le Marionette app.vent (che è il trasmettitore di eventi globale per la nostra applicazione), a cui si aggiunge js e funziona davvero bene.

app

define(, function(){ 
    return new Backbone.Marionette.Application(); 
}) 

Model1

define(['app'], function(app){ 
    return Backbone.Marionette.Model.extend({ 
    initialize: function(){ 
     this.bindTo('app.vent', 'create:model2', this.toSomething, this); 
    } 
    }) 
}) 

Model2

define(['app'], function(app){ 
    return Backbone.Marionette.Model.extend({ 
    initialize: function(){ 
     app.vent.trigger('create:model2', this); 
    } 
    }) 
}) 
+0

Buono a sapersi che Marionette va bene con require.js. Tuttavia, non esiste una soluzione al problema che non implichi un quadro aggiuntivo/alternativo? – alearg

+0

Ci sono un sacco di soluzioni. Posso consigliare PubSubJS: https://github.com/mroderick/PubSubJS –

+0

Grazie per il tuo suggerimento, darò un'occhiata a questo. Ma non ci sono soluzioni che non implichino alcun quadro aggiuntivo? – alearg