2012-04-12 35 views
6

Tôi đang thiết lập một ứng dụng được điều khiển bởi Backbone. Tôi đang đối mặt với một vấn đề "nên đơn giản", nơi tôi có một Mô hình gọi là "Thông điệp", một Bộ sưu tập được gọi là "MessageList" và các Chế độ xem được gọi là "MessageView" và "MessageListView".Bộ sưu tập xương sống - Lọc và hiển thị Bộ sưu tập mất tham chiếu đến Bộ sưu tập chưa được lọc ban đầu

Mã MessageListView hiển thị Danh sách thư. Tôi có 4 nút chuyển đổi để lọc những gì mà MessageListView hiển thị. Các nút bộ lọc là "Tất cả", "Hoạt động", "Đã gắn cờ" và "Đã bỏ qua". "Tất cả" là bộ lọc ban đầu khi tải trang. Khi người dùng nhấn vào bộ lọc "Được gắn cờ", chỉ những Tin nhắn có cờ == 1 mới xuất hiện. Khi "Tất cả" được nhấn một lần nữa, tất cả các Tin nhắn sẽ xuất hiện trở lại.

Sự cố tôi đang gặp phải và sự cố trong thiết kế của tôi là khi tôi lọc Bộ sưu tập dựa trên bộ lọcString, tham chiếu đến toàn bộ Bộ sưu tập gốc bị mất. Vì vậy, khi "Tất cả" được nhấn một lần nữa, Tin nhắn đã bị mất.

Tôi tò mò như cách tốt nhất để làm điều này trong Backbone ...

Dưới đây là các mã cài đặt ...

var messageListView = new MessageListView({collection: messageList}); 

Dưới đây là đoạn code MessageListView ...

MessageListView = Backbone.View.extend({ 

    initialize : function() { 

     this.collection.on("add", function(model) { 
      var view = new MessageView({model: model}); 
      $("div.cameras").prepend(view.render().el); 
     }); 

     this.collection.on("remove", function(model) { 
      var ID = model.id; 
      $("#message-" + ID).parent("div.message").remove(); 
     }); 

     this.collection.on("reset", function(models) { 
      $("div.cameras").empty(); 
      models.each(function(message) { 
       var view = new MessageView({model: message}); 
       $("div.cameras").prepend(view.render().el); 
      }); 
     }); 

    }, 

    filterMessages : function(filterString) { 
     var filtered = this.collection.filter(function(model){ 

      if (filterString == "all") 
      { 
       return true; 
      } 
      else if (filterString == "active") 
      { 
       return model.get("ignore") == "0"; 
      } 
      else if (filterString == "ignore") 
      { 
       return model.get("ignore") == "1"; 
      } 
      else if (filterString == "flag") 
      { 
       return model.get("flag") == true; 
      } 

     }); 
     this.collection.reset(filtered); 
    }, 
+0

Tôi upvoted cả các câu hỏi và câu trả lời, nhờ chàng trai. Chỉ cần một gợi ý cho OP: Tôi thà đặt các chức năng lọc (s) trong Collection itselft và không phải là xem. Có điều này nói rằng thế giới MVC, "Mô hình béo, bộ điều khiển gầy". Trong Backbone, View hoạt động như bộ điều khiển. Và thực tế là các bộ sưu tập của Backbone có các chức năng của Underscore là một gợi ý theo hướng đó. – DjebbZ

Trả lời

10

Khi bạn gọi

this.collection.reset(filtered) 

Bạn đang vứt bỏ dữ liệu cũ và thay thế dữ liệu đó bằng dữ liệu mới.

Điều bạn muốn làm thay vào đó là có một 'bộ sưu tập' tạm thời (mảng hoặc Backbone.Collection) để giữ kết quả của bộ lọc và THAT là những gì bạn sử dụng làm 'nguồn dữ liệu' để hiển thị Tin nhắn của bạn DOM.

Có một vài cách bạn có thể thực hiện việc này.

  1. Chỉ cần hiển thị đầu ra [mảng] của hàm filterMessages trong mọi trường hợp (bao gồm trường hợp 'tất cả') - nhưng không đưa kết quả đó trở lại bộ sưu tập gốc.
  2. Tạo bộ sưu tập thứ hai để nhận kết quả của hàm filterMessages và hiển thị lại một lần nữa, để nguyên bộ sưu tập ban đầu của bạn.
4

Bạn có thể sử dụng Backbone.CollectionView, cho phép bạn chỉ định kiểu máy nào trong bộ sưu tập hiện được hiển thị bằng tùy chọn visibleModelsFilter.

đang cài đặt ...

var messageListView = new MessageListView({ 
    collection: messageList, 
    modelView : MessageView 
}); 

đang MessageListView ...

MessageListView = Backbone.CollectionView.extend({ 

    filterMessages : function(filterString) { 
     if (filterString == "all") { 
      this.setOption("visibleModelsFilter", null); 
     } 
     else if (filterString == "active") { 
      this.setOption("visibleModelsFilter", function(thisModel) { 
       return model.get("ignore") == "0"; 
      }); 
     } 
     else if (filterString == "ignore") { 
      this.setOption("visibleModelsFilter", function(thisModel) { 
       return model.get("ignore") == "1"; 
      }); 
     } 
     else if (filterString == "flag") { 
      this.setOption("visibleModelsFilter", function(thisModel) { 
       return model.get("flag") == true; 
      }); 
     } 
    } 

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