2012-09-13 11 views
16

Mam wiele modeli szkieletowych, zorganizowanych w kolekcje i połączonych z ich odpowiednimi widokami i/lub kolekcjami widoków. Niektóre z tych modeli, które nie należą do tej samej kolekcji, muszą wywołać zdarzenie, które jest interesujące dla innego modelu (i może więcej niż jednego).backbone.js + globalny dispatcher zdarzeń + require.js: how-to?

Zalecanym sposobem radzenia sobie z tym jest, jak sądzę, "globalny moduł rozsyłający zdarzenia/agregator" zgodnie z opisem here i innymi miejscami.

Jednak zdarza mi się też używać require.js, co wydaje się sprzeczne z ideą dołączenia modułu rozsyłającego/agregatora do obiektu przestrzeni nazw aplikacji - czy też się mylę?

Moje pytanie brzmi: użycie require.js w jaki sposób mogę mieć wiele różnych modeli szkieletu wyzwalać zdarzenie, które będzie obsługiwane przez inny model?

Odpowiedz

35

Podobne rozwiązanie do czego @Andreas p roposed ale bez Backbone.Marionette (mocno zainspirowany jednak, see the article linked in the question).

Wszystko, co musisz zrobić, to zdefiniować moduł, który tworzy singleton obiektu nasłuchującego zdarzenia i wymagać tego obiektu w modułach, w których chcesz wywołać zdarzenie lub odsłuchać to wydarzenie.

Powiedzmy masz APP/channel.js określających swój kanał

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

Następnie można użyć go jako słuchacza poprzez

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

i można wyzwolić zdarzenie na ten kanał przez

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

Myślę, że tego właśnie szukałem. Wielkie dzięki nikoshr i andreas – alearg

+0

Jaka jest zaleta korzystania z wydarzeń w tej sytuacji? Nadal musimy uwzględnić "app/model" we wszystkich modułach, w których chcemy wywołać to zdarzenie. Dlaczego nie wykonać api api na tym modelu? – wizardzloy

+1

@wizardzloy Jedynym modułem, który musisz uwzględnić, jest 'app/channel', w którym chcesz odsłuchać lub wywołać zdarzenie globalne. 'app/model' służy tylko do zademonstrowania użycia próbki. – nikoshr

1

Używamy marionetek app.vent (który jest globalnym nadajnikiem zdarzeń dla naszej aplikacji), allong z wymaganiem js i działa naprawdę dobrze.

aplikacja

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

Dobrze wiedzieć, że marionetka jest w porządku z require.js. Czy jednak nie ma rozwiązania problemu, który nie wiąże się z dodatkowymi/alternatywnymi ramami? – alearg

+0

Istnieje kilka rozwiązań. Mogę doradzić PubSubJS: https://github.com/mroderick/PubSubJS –

+0

Dzięki za twoją sugestię, przyjrzę się temu. Ale czy nie ma rozwiązań, które nie obejmowałyby dodatkowego schematu? – alearg