2012-03-01 31 views
19

Tôi có một PageView cấp cao nhất sẽ tự hiển thị lại bất cứ khi nào tuyến đường thay đổi. Tôi có nhiều khung nhìn con lồng nhau được nhúng vào PageView này. Nếu tôi phải trả lại PageView, tôi có cần xóa/hủy liên kết tất cả các khung nhìn con lồng nhau cùng với PageView hay tôi chỉ cần xóa/hủy liên kết PageView? Nếu tôi cần xóa/hủy liên kết tất cả các chế độ xem phụ, cách tốt nhất để thực hiện việc này là gì?Backbone.js - Xóa tất cả các chế độ xem phụ

+0

Bạn có ý gì bằng cách hủy liên kết các chế độ xem phụ? Bạn có nghĩa là sự kiện? – Trevor

Trả lời

35

Có, bạn cần phải loại bỏ đúng cách và unbind họ:

http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

Cách đơn giản để làm điều này là để lưu trữ một loạt các phụ quan điểm của bạn trong giao diện cha mẹ. Sau đó, trong một phương pháp close trên quan điểm phụ huynh, lặp qua mảng và gọi một phương thức close trên quan điểm con:

ParentView = Backbone.View.extend({ 
    initialize: function(){ 
    this.childViews = []; 
    }, 

    render: { 
    for (var i = 0; i < 10; i++){ 
     var childView = new ChildView(); 
     // do stuff with the child view 
     this.childViews.push(childView); 
    } 
    }, 

    close: function(){ 
    this.remove(); 
    this.unbind(); 
    // handle other unbinding needs, here 
    _.each(this.childViews, function(childView){ 
     if (childView.close){ 
     childView.close(); 
     } 
    }) 
    } 
}); 

Hãy chắc chắn để gọi phương thức close trên quan điểm phụ huynh khi bạn đã sẵn sàng cho nó được đã xóa/thay thế. Điều này sẽ đảm bảo tất cả các trẻ em được làm sạch đúng cách (giả sử tất cả trẻ em đều có phương pháp close riêng của chúng).

+0

Hey Derick, tôi đã theo lời khuyên của bạn về điều này nhưng tôi gặp phải sự chậm trễ thực sự lâu dài khi đóng một chế độ xem + đó là chế độ xem con. Trong một số trường hợp, nó có thể kéo dài 5-10 giây. Dường như sự chậm trễ đến từ this.remove(). Bạn có ý tưởng gì không? – ragulka

+0

đó là khá dài, và khủng khiếp! Tôi chưa bao giờ thấy điều đó xảy ra, thành thật mà nói ... cấu trúc DOM mà bạn đang loại bỏ lớn đến mức nào? Đoán duy nhất của tôi sẽ là một trình duyệt thực sự chậm, và/hoặc một tập nút DOM rất lớn. –

+0

Hey, nevermind - có vẻ như đó là một vấn đề với một plugin jquery thay vào đó là bằng cách nào đó xung đột với chức năng remove() của khung nhìn: http://stackoverflow.com/questions/9877786/calling-jquery-remove-on-custom-ui -widget-cause-infinite-loop/9878287 # 9878287 – ragulka

2

Thay vì giữ một loạt chế độ xem trẻ em, có thể lặp qua tất cả các thuộc tính của chế độ xem của bạn và xem những thuộc tính nào là một thể hiện của Backbone.View; bạn cần đảm bảo đặt thuộc tính cho mỗi chế độ xem con trong chế độ xem cha mẹ của bạn.

Trong ví dụ bên dưới, chế độ xem con được đặt thành thuộc tính của chế độ xem gốc. Tôi không chắc chắn những gì hiệu suất hit sẽ được looping thông qua tất cả các tài sản, tuy nhiên, nó có thể được dễ dàng hơn so với theo dõi của một cấu trúc dữ liệu riêng biệt cho các quan điểm trẻ em.

Ví dụ:

var ContextView = Backbone.View.extend({ 
    initialize: function() { 
     // views render themselves via their initialize methods 
     this.titlebar = new TitlebarView({el: $("#titlebar")});  
     this.toolbar = new ToolbarView({el: $("#toolbar")}); 
     this.content = new ContentView({el: $("#content")}); 
    }, 
    removeChildViews: function() {  
     for(var prop in this){ 
      if (this[prop] instanceof Backbone.View) { 
       console.log("This is a view: "+ prop + ' in ' + this[prop]);  
      } 
     } 
    }, 
    render: function() { 
     this.$el.html(this.el); 
    } 
    }); 
3

Một lớp học đơn giản và mô-đun bạn có thể thấy hữu ích.

ContainerView = Backbone.View.extend({ 
    initialize: function() { 
    this.children = []; 
    }, 
    remove: function() { 
    Backbone.View.prototype.remove.apply(this, arguments); 
    this.removeAllChildren(); 
    }, 
    removeAllChildren: function() { 
    _.each(this.children, function(view) { view.remove(); }); 
    this.children = []; 
    }, 
    appendAllChildren: function() { 
    _.each(this.children, function(view) { this.$el.append(view.render().$el); }, this); 
    } 
}); 

sử dụng:

MyView = ContainerView.extend({ 
    render: function() { 
    this.removeAllChildren(); 
    this.$el.empty(); 

    // For each child view... 
    // this.children.push(new SomeControl(...)); 

    this.appendAllChildren(); 
    return this; 
    } 
}); 
0

Một chút giống như Zengineer đã viết, tôi muốn vá Backbone.View.remove toàn cầu như sau, để cho bất kỳ quan điểm con kèm theo về vấn đề này được loại bỏ

var originalRemove = Backbone.View.prototype.remove; 

Backbone.View.prototype.remove = function() 
{ 

    for (var view in this){ 
    if (this[view] instanceof Backbone.View && this[view] != this) { 
     this[view].remove(); 
    } 
    } 


    originalRemove.apply(this, arguments); 

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