2012-02-22 13 views
19

Mam app szkieletowej ze strukturą widoku, który wygląda następująco - zauważ, że usunęliśmy implementacje, modele, kolekcje, itp dla zwięzłości:Jak mogę spaprać zdarzenia w hierarchii widoku kręgosłupa?

NewsListView = Backbone.View.extend({ 

    el: $('li#newspane'), 

    // This is what I would like to be able to do 
    // events: { 'filtered': 'reset' } 

    initialize: function() { 
     _.bindAll(this); 
    }, 

    render: function() { 
    }, 

    reset: function(){ 
    } 

}); 

FilterView = Backbone.View.extend({ 

    el: $('li.filter'), 

    initialize: function() { 
    }, 

    render: function() { 
    }, 

    toggleFilter: function() { 
    } 

}); 

AllView = Backbone.View.extend({ 

    initialize: function() { 

     this.newsListView = new NewsListView(); 
     this.filterView = new FilterView(); 

    } 

}); 

Zasadniczo, gdy toggleFilter() funkcja FilterView „s nazywa się, chciałbym wystrzelić zdarzenie o nazwie filtered lub coś podobnego, które następnie zostanie przechwycone przez NewsListView, która następnie wywołuje jego funkcję reset(). Nie przekazując odniesienia do obiektu NewsListView do mojego FilterView, nie jestem pewien, jak wysłać to zdarzenie. Jakieś pomysły?

Odpowiedz

0

Więc wymyśliłem rozwiązanie - utwórz obiekt rozszerzający Backbone.Events i przekazuj go jako parametr do wielu widoków. To prawie wydaje się być komunikatem między aktorami lub czymś podobnym. W każdym razie - zamieszczam to jako odpowiedź na wypadek, gdyby ktoś inny potrzebował szybkiego rozwiązania, ale nie zamierzam przyjąć odpowiedzi. To wydaje się być hacky. Nadal chciałbym znaleźć lepsze rozwiązanie.

NewsListView = Backbone.View.extend({ 
    el: $('li#newspane'), 

    // Too bad this doesn't work, it'd be really convenient 
    // events: { 'filtered': 'reset' } 

    initialize: function() { 
     _.bindAll(this); 
     // but at least this does 
     this.options.eventProxy.bind('filtered', this.reset); 
    }, 
    render: function() {}, 
    reset: function() {} 
}); 

FilterView = Backbone.View.extend({ 
    el: $('li.filter'), 

    initialize: function() {}, 
    render: function() {}, 
    toggleFilter: function() { 
     this.options.eventProxy.trigger('filtered'); 
    } 
}); 

AllView = Backbone.View.extend({ 
    initialize: function() { 
     var eventProxy = {}; 
     _.extend(eventProxy, Backbone.Events); 
     this.newsListView = new NewsListView({eventProxy: eventProxy}); 
     this.filterView = new FilterView({eventProxy: eventProxy}); 
    } 
}); 
0

Ten problem można rozwiązać za pomocą małego hakowania backbone.js. Wystarczy zmodyfikować Backbone.Events.trigger przekazywania zdarzeń do this.parent

if this.parent != null 
3

Może być można to zrobić za pomocą już dostępnych funkcji zdarzeń jquery i właściwości zdarzeń szkieletowych.

Na przykład, zamiast robić to od wewnątrz podrzędny:

this.trigger("yourevent", this); 

to zrobić w zamian:

this.$el.trigger("yourevent", this); 

Następnie w dowolnym widoku, który jest rodzic, dziadek itd swojego widzenia dziecka , posłuchaj zdarzenia na elemencie $ tego widoku, definiując właściwość obiektu zdarzenia tego widoku:

events:{ 
    "yourevent":"yourhandler" 
} 

oraz określić procedurę obsługi w tym widoku, a także:.

yourhandler:function(subview) { 
} 

Więc w ten sposób, widok nie musi wiedzieć o tym, co istnieje potomek widoki, tylko rodzaj zdarzenia jest zainteresowana Jeśli widok pochodzące wydarzenie jest niszczone, nic nie musi się zmieniać w widoku przodków. Jeśli widok przodka zostanie zniszczony, Backbone automatycznie odłączy moduły obsługi.

Zastrzeżenie: Nie wypróbowałem tego jeszcze, więc może gdzieś tam jest grosz.

+0

To nie działa dla mnie. – anyaelise

+0

Dziękuję za aha! za chwilę. –

0

Najprostszym sposobem wyzwalania i słuchania zdarzeń jest użycie samego obiektu Szkielet.Ma już wydarzenia funkcje mieszane w niej, więc można po prostu wywołać np:

Backbone.trigger('view:eventname',{extra_thing:whatever, thing2:whatever2}); 

Następnie w inny widok szkieletowej w swojej aplikacji można słuchać na tym wydarzeniu, np:

Backbone.on('view:eventname', function(passed_obj) { 
    console.log(passed_obj.extra_thing); 
}); 

Nie jestem do końca pewien, co jest zaletą, jeśli nie używamy obiektu Backbone jako narzędzia obsługi zdarzeń, a zamiast tego tworzy się oddzielny obiekt do tego celu, ale do szybkiego i brudnego działania, powyższe działa dobrze. HTH!

UWAGA: jedną wadą jest to, że każdy słuchacz "usłyszy" każde wydarzenie wywołane w ten sposób. Nie jestem pewien, o co chodzi w tym wielkim O, ale pracuj uważnie, aby nie przeciążać swoich poglądów dużą ilością tych rzeczy. Znowu: to jest szybkie i brudne! :)

Powiązane problemy