2012-05-22 35 views
5

Ok, vì vậy tôi có điều hướng và khái niệm về trang tổng quan. Trong bộ định tuyến của tôi khi tôi nhấp vào liên kết điều hướng, tôi đang gọi trên chế độ xem trang tổng quan của mình để đặt tab hoạt động.sử dụng div đơn lẻ làm vùng chứa cho nhiều chế độ xem xương sống mất liên kết sự kiện

Ví dụ:

NAV

<a href="#" class="dashabord_tab" id="widgets">Widgets</a> 
<a href="#" class="dashabord_tab" id="Foobars">Foobars</a> 

dashboard_container.jst.tpl

<div id="nav"></div> 
<div id="current_tab"></div> 

DASHABORDVIEW

DashboardView = Backbone.View.extend({ 
    template:JST.dashboard_container, 
    render: function(){ 
    $(this.el).html(this.template()); 
    }, 
    activateWidgets: function(){ 
    if(!(this.widgets_view)){ 
     this.widgets_view = new WidgetsView(); 
     this.widgets_view.render(); 
    } 
    $(this.el).find("#current_tab").html(this.widgets_view.el); 
    }, 
    activateFoobars: function(){ 
    if(!(this.foobars_view)){ 
     this.foobars_view = new FooBarsView(); 
     this.foobars_view.render(); 
    } 
    $(this.el).find("#current_tab").html(this.foobars_view.el); 
    } 
}); 

vấn đề:

Vì vậy, lần đầu tiên tôi chuyển sang widgets_tab hoặc foobar_tab tab tải như mong đợi. Tuy nhiên, nếu tôi chuyển sang một tab, hãy chuyển sang tab, sau đó chuyển lại, tất cả các sự kiện trong chế độ xem của tôi sẽ không còn bị ràng buộc nữa. Nhấp, hoevering, không ai trong số các quan điểm bên trong foobars_view ví dụ đều có thể click, hoverable vv

Trong quá khứ, tôi đã thực hiện một wrapper cho mỗi một trong những quan điểm con như vậy:

giải pháp trong quá khứ, pita:

activateFoobars: function(){ 
    $('.tab_wrapper').hide(); 
    if($(this.el).find("#foobars_wrapper").length < 1){ 
     $(this.el).append("<div class='tab_wrapper' id='foobars_wrapper'></div>"); 
     this.foobars_view = new FooBarsView(); 
     $(this.el).find("#foobars_wrapper").html(this.foobars_view.render().el); 
    } 
    $('#foobars_wrapper').show(); 
    } 

tôi không muốn làm điều đó theo cách tôi chỉ trình bày ở trên, và tôi thực sự thích ý tưởng chỉ cần đặt el của view trong một div active_tab luôn vẫn mở ... Nếu tôi có thể' Tôi làm theo cách tôi muốn, có cách nào khác thay cho cách tôi vừa trình bày ở trên không? Cảm ơn!

Trả lời

5

Khi bạn sử dụng .html(dom_object):

$(this.el).find("#current_tab").html(this.widgets_view.el); 

Bạn đang thực sự làm điều này:

$(this.el).find('#current_tab').empty().append(this.widgets_view.el); 

empty:

loại bỏ các cấu trúc khác như dữ liệu và xử lý sự kiện từ các phần tử con trước khi tự xóa các phần tử [Để tránh rò rỉ bộ nhớ]

Vì vậy, một khi bạn đã thêm, nói, -#current_tab và sau đó .html(this.foobars_view.el), sự kiện trên widgets_view.el đã mất hết. Cuộc gọi .html của bạn hoạt động tốt lần đầu tiên vì không có gì trong số #current_tab do đó không có bất kỳ sự kiện nào để hủy liên kết.

Bạn có thể sử dụng "tái sử dụng các quan điểm" cách tiếp cận của bạn bằng cách thêm delegateEvents cuộc gọi đơn giản vào trộn để rebind sự kiện:

activateWidgets: function(){ 
    if(!(this.widgets_view)){ 
    this.widgets_view = new WidgetsView(); 
    this.widgets_view.render(); 
    } 
    $(this.el).find("#current_tab").html(this.widgets_view.el); 
    this.widgets_view.delegateEvents(); // <--------------- you need this 
} 

Trong khi tôi đang ở đây, bạn có thể sử dụng this.$('#current_tab') thay vì $(this.el).find('#current_tab')this.$el thay của $(this.el).

Demo: http://jsfiddle.net/ambiguous/75KuW/1/

Lưu ý rằng việc chuyển đổi các tab ở trên bảo tồn nội dung của <input type="text"> yếu tố. Nếu bạn không cần loại hành vi đó thì có lẽ bạn nên loại bỏ và khởi tạo chế độ xem khi cần thiết thay vì giữ tất cả các chế độ xem và trao đổi chúng trong và ngoài.

Ngoài ra, nếu WidgetsView (và bạn bè) của bạn có các chế độ xem Xương sống khác bên trong chúng, bạn sẽ phải gọi delegateEvents trên các chế độ xem đã bao gồm hết. Trong trường hợp này, một số loại bind_events phương pháp trên quan điểm sẽ có ý nghĩa:

this.widgets_view.rebind_events(); // delegateEvents() all the way down this view subtree 
+0

rằng hoạt động tuyệt vời trong ví dụ jsfiddle của bạn ... đối với một số lý do, nó không làm việc trong ứng dụng của tôi. Tôi nên lưu ý rằng widgetsview và foobarview đều có chế độ xem con của riêng chúng. Điều đó làm cho một sự khác biệt? – jdkealy

+0

@ jdkealy: Có thể bạn sẽ cần 'delegateEvents' tất cả các con đường xuống khi cuộc gọi' empty' sẽ giết chết ** tất cả ** các ràng buộc sự kiện. Một phương thức (nói 'rebind_all_events') trên các khung nhìn mà các' delegateEvents' cần thiết sẽ có ý nghĩa để giữ cho mọi thứ được đóng gói đúng cách. –

+0

Ahhh, tôi thấy bây giờ, khi tôi đặt trong một cái nhìn đơn giản, nó hoạt động tuyệt vời ... Vâng quan điểm của tôi đi quá sâu Tôi nghĩ rằng để gọi delegateEvents tất cả các con đường xuống chuỗi. Điều này là tốt để biết để tham khảo trong tương lai, nhưng tôi nghĩ rằng tôi sẽ đi với các hiển thị/ẩn hoặc phương pháp bù đắp. Cảm ơn! – jdkealy

Các vấn đề liên quan