2012-11-27 38 views
8

Tôi đang cố gắng để làm cơ bản render() sau khi lấy() trên bộ sưu tập (Backbone 0.9.2):Debugging Backbone.js: vẽ sau khi bộ sưu tập lấy()

var ProjectListView = Backbone.View.extend({ 
     el: $('#container'), 
     initialize: function() { 
      this.collection = new ProjectsCollection(); 
      this.collection.bind("change", _.bind(this.render, this)); 
      this.collection.fetch({ success: function() { console.log("collection fetched"); } }); 
      ... 
      }, 
     render: function() { 
      console.log("rendered"); 
      ... 

Tạo mới in Xem dụ ra :

collection fetched

Vì vậy, kết xuất() không bao giờ được gọi sau khi tìm nạp(). Tôi làm gì sai ở đây? Không có ngoại lệ.

Bất kỳ mẹo nào về cách gỡ lỗi những thứ này trong xương sống?

Ps. Dường như tính năng này kém tài liệu do số lượng câu hỏi về SO.

Trả lời

28

Từ fine manual:

lấycollection.fetch([options])

Fetch tập hợp các mô hình mặc định cho bộ sưu tập này từ máy chủ, đặt lại bộ sưu tập khi họ đến. [...] Khi dữ liệu mô hình trả về từ máy chủ, bộ sưu tập sẽ đặt lại.

reset làm gì? reset thực hiện điều này:

resetcollection.reset(models, [options])

[...] Sử dụng reset để thay thế một bộ sưu tập với một danh sách mới của mô hình (hoặc thuộc tính băm), gây ra một sự kiện duy nhất "reset" tại kết thúc.

Vì vậy fetch gọi reset để cập nhật mô hình của bộ sưu tập và reset kích hoạt sự kiện "reset", không phải là một sự kiện "change". Không có mô hình nào đã thay đổi và các sự kiện "change" của bộ sưu tập xuất phát từ các mô hình của nó.

Bạn nên đã render ràng buộc để "reset":

initialize: function() { 
    this.collection = new ProjectsCollection(); 
    this.collection.bind("reset", _.bind(this.render, this)); 
    this.collection.fetch(...); 
} 

Nếu bạn muốn nghe cho "change" sự kiện trên các mô hình chứa sau đó bạn có thể gắn một handler "change" đến việc thu thập since:

Bạn có thể liên kết "change" sự kiện để được thông báo khi bất kỳ mô hình nào trong bộ sưu tập đã được sửa đổi,
[...]
Bất kỳ sự kiện nào được kích hoạt trên một mô hình trong bộ sưu tập cũng sẽ được kích hoạt trực tiếp trên bộ sưu tập, để thuận tiện.

Bộ sưu tập cũng sẽ tạo ra các sự kiện "add""remove" khi chính bộ sưu tập thay đổi.


Mới hơn phiên bản của Backbone không còn bộ sưu tập thiết lập lại trong fetch:

Khi trở về mô hình dữ liệu từ máy chủ, nó sử dụng thiết đến (thông minh) kết hợp các mô hình lấy, trừ khi bạn vượt qua {reset: true}, trong trường hợp đó, bộ sưu tập sẽ (hiệu quả) đặt lại.

set:

[...] thực hiện một "thông minh" cập nhật của bộ sưu tập với danh sách thông qua các mô hình. Nếu một mô hình trong danh sách chưa có trong bộ sưu tập, nó sẽ được thêm vào; nếu mô hình đã có trong bộ sưu tập các thuộc tính của nó sẽ được hợp nhất; và nếu bộ sưu tập chứa bất kỳ mô hình nào không có trong danh sách, chúng sẽ bị xóa. Tất cả các hợp "add", "remove", và "change" sự kiện được bắn như thế này xảy ra

Vì vậy, với các phiên bản mới hơn của Backbone bạn sẽ muốn liệt kê cho "add", "remove", và "change" sự kiện (mà một cái nhìn bộ sưu tập dựa nên vẫn lắng nghe); bạn cũng có thể sử dụng {reset: true} trên số fetch ban đầu và nghe theo số "reset". Tôi khuyên bạn nên phương pháp sau đây để xem bộ sưu tập dựa trên:

  1. Nghe "add" và xử lý các sự kiện với một callback mà chỉ cần thêm một mục để xem, không ném tất cả mọi thứ đi và tái render.
  2. Nghe "remvoe" và xử lý sự kiện đó bằng gọi lại chỉ xóa mô hình mới bị xóa.
  3. Nghe "change" và xử lý việc đó bằng cách gọi lại thay thế (hoặc cập nhật) mục thích hợp.
  4. Nghe "reset" và liên kết điều đó với render. Sau đó, hãy chuyển số {reset: true} vào cuộc gọi fetch ban đầu của bộ sưu tập.

Điều đó sẽ bẫy các sự kiện quan trọng và chế độ xem bộ sưu tập sẽ làm lượng công việc tối thiểu để xử lý từng sự kiện. Tất nhiên, chiến lược này không áp dụng được cho mọi tình huống nhưng tôi nghĩ đó là một điểm khởi đầu tốt.

+0

Cảm ơn bạn đã trả lời kỹ lưỡng, hy vọng điều này sẽ hữu ích cho người khác. PS. Có các tài nguyên khác mà bạn có thể đề xuất bên cạnh tài liệu chính thức không? – Fdr

+0

@Fdr: Tôi đã đọc tài liệu và mã nguồn để tham khảo. Và sau hơn 15 năm, tất cả các khuôn khổ trông khá giống nhau. –

+0

Tôi đoán vậy.Những sự kiện này trong xương sống là một chút vấp ngã: "thiết lập lại" được nâng lên cho các bộ sưu tập, nhưng không có sự giống nhau khi thực hiện model.fetch() (nguyên nhân "thay đổi" được phát ra). Thiết kế api yếu? – Fdr

3

Ok, vậy cho đến khi một số ai có thể giải thích tại sao ràng buộc đã không làm việc, tôi đã sử dụng sau workaround:

initialize: function() { 
      var self = this; 
      this.collection = new ProjectsCollection(); 
      this.collection.fetch({ success: function() { self.render(); } }); 

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