2013-03-06 10 views
6

Mam Layout, który ma kilka zakładek. Kliknięcie jednej z tych zakładek spowoduje wyświetlenie odpowiedniego widoku złożonego w treści strony region. Po przejściu między kartami zauważyłem, że widoki złożone utraciły swoje macierzyste wiązania do renderowania po zresetowaniu kolekcji i zmianach modelu.Backbone.marionnette - Rebinding events vs Creating New View

Czy istnieje sposób ponownego wiązania zdarzeń używanych w _initialEvents widoku złożonego podczas pokazywania widoku po raz drugi, lub powinienem być tworzenie nowego widoku złożonego, każdy I show tab?

Obecnie tworzę wszystkie moje widoki w initialize mojego Layout, a następnie używając show z widokiem po kliknięciu karty.

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

    //  Tabs 
    this.places_page = new Places_Layout(); 
}, 

show_places_page: function(){ 

    this.content.show(this.places_page); 
    this.places_page.delegateEvents(); 
}, 
+1

Tak, myślę, że należy utworzyć nowy kompozytowy widok istance każdym razem trzeba zmienić treść, to dlatego, że po wywołaniu metody Pokaż na obszarze dba aby zamknąć i odłączyć dowolny stary widok dołączony do regionu. Więc myślę, że po dołączeniu go do regionu ponownie przegapił kilka wydarzeń ... – Ingro

Odpowiedz

0

To nie brzmi jak najlepsze podejście do mnie.

Powinieneś używać menedżerów regionów układu, aby wyświetlać widoki bez funkcji, które już zdefiniowałeś.

pójdę za tym podejściem

var view = new CustomView(); 
layout.content.show(view);` 

potem na:

var newView = new SecondCustomView(); 
layout.content.show(newView); 

Jeśli chcesz kontynuować w dół drogi, że jesteś na to byś prawdopodobnie najlepiej użyć tego podejścia :

initialize: function() { 
    _.bindAll(this); 
}, 
show_places_page: function() { 
    var placesLayout = new Places_Layout(); 
    this.content.show(placesLayout); 
} 

Czy to ma sens?

Trudno zasugerować najlepszy sposób działania, nie widząc więcej struktury wokół tego.

Czy istnieje powód, dla którego tworzysz widoki w initialize?

0

Marionetka (v.1) hasło używa Backbone.BabySitter do zarządzania widokami podrzędnymi.

W twoim przypadku robisz to samo. Po prostu utwórz pojemnik do przechowywania widoku wszystkich kart. Później zapytaj kontener, aby zwrócił widok, który chcesz wyświetlić.

this.tabViewsContainer = new Backbone.ChildViewContainer(); 
this.tabViewContainer.add(new CustomView(),'tab1'); 
this.tabViewContainer.add(new SecondCustomView(),'tab2'); 

później pokaż widok po prostu zrób to

var custv = container.findByCustom("tab1"); 
this.content.show(custv); 

W ścisłej metody Twój widok układ z powodzeniem zamknąć wszystko Widok w pojemniku

this.tabViewsContainer.each(function(view){view.close()}); 
1

Nie don stworzyć układ/Widok pozycji/złożenia/kolekcji za każdym razem, gdy przełączasz się z karty na kartę, ale możesz zapisać zawartość w zmiennej tak, jak robisz, problem polega na tym, że zmienna jest ponownie deklarowana. czas, kiedy chcesz renderować zawartość. Rozwiązaniem jest to, że musisz zweryfikować, czy ta zmienna (this.places_page) jest zadeklarowana, jeśli nie jest dołączona do widoku, więc gdy będziesz go wywoływał więcej razy, będzie miał ten sam widok układu bez problemu, po prostu zauważ, że kiedy render główny widok (ten, w którym znajdują się regiony) zagnieżdżone widoki podrzędne (w regionach) zostaną utracone do czasu nowej przebudzenia za ich pośrednictwem.

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

    // You can asign a diferent variable for each view so when you call show_places_page it will render with the same view. 

    if (!this.places_page){ 
     this.places_page = new Places_Layout(); 
    } 

    // other tab   
    if (!this.other_page){ 
     this.other_page = new OtherPage_Layout(); 
    } 

}, 

show_places_page: function(){ 

    this.content.show(this.places_page); 
    this.places_page.delegateEvents(); 
}, 
0

Nie należy tworzyć wszystkie widoki wewnątrz initialize jak będzie to spowodować wycieki pamięci, dlatego należy zrobić dynamiczne tworzenie widoków. Proponuję również utworzyć wspólną funkcję wyświetlania widoku w regionie treści, aby zwiększyć ponowne użycie kodu. Proponuję coś takiego następujące rozwiązanie:

//define the regions of your layout view 
regions: { 
    content: '#content' 
}, 
//Maintain a config for the tab content view classes. 
contentViews: { 
    tab1: Tab1View, 
    tab2: Tab2View, 
    tab3: Tab3View 
}, 
//keeps all the view instances 
viewInstances: {}, 
/* 
* show tab function is called when you click a tab item. 
* Consider each tab has a attribute for tab name. 
* For example HTML of your one tab is like: 
* <div data-tab-name="tab_name">Tab <tab_name></div> 
*/ 
showTab: function (e) { 
    var tabName = $(e.currentTarget).attr("data-tab-name"); 
    /* 
    * code for showing selected tab goes here... 
    */ 

    //check and create the instance for the content view 
    if (!this.viewInstances[tabName]) { 
     this.viewInstances[tabName] = new this.contentViews[tabName](); 
    } 
    //Then here you are actually showing the content view 
    this.content.show(this.viewInstances[tabName]); 
    this.viewInstances[tabName].delegateEvents(); //this is to rebind events to the view. 
}