2012-10-26 43 views
14

Có một thứ đơn giản mà tôi thiếu ở đây.Phương pháp chuỗi xương sống/Gạch dưới với phương thức

http://jsfiddle.net/v9mdZ/

Tôi chỉ học Backbone và gạch/loDash và đang cố gắng để làm quen với chain.

Tôi đã đoạn mã sau, mà làm việc như mong đợi:

var ids = _.pluck(collection.where({'is_checked':true}), 'id'); 

Tôi đã cố gắng để cấu trúc lại này, sử dụng chain như vậy:

var ids = collection.chain().where({'is_checked':true}).pluck('id').value(); 

Tại sao không phải là công việc mã refactored? Tôi có đang sử dụng chain không?

Solution (xem chi tiết bên dưới)

Không sử dụng where với chain.

Trả lời

18

Việc hợp nhất some Underscore methods vào bộ sưu tập là một chút không hoàn hảo. Khi bạn nói collection.some_mixed_in_underscore_method(), bộ sưu tập sẽ unwraps một số công cụ Backbone đằng sau lưng của bạn để phương pháp Underscore được áp dụng cho các thuộc tính bên trong các mô hình của bộ sưu tập; nó loại công trình như thế này:

var ary = _(this.models).map(function(m) { return m.attributes }); 
return _(ary).some_mixed_in_underscore_method(); 

Nhưng collection.chain() không hoạt động như vậy, chain chỉ kết thúc tốt đẹp bộ sưu tập của models trực tiếp vì vậy nếu bạn làm điều này:

console.log(collection.chain()); 

bạn sẽ thấy rằng chain là cho bạn một đối tượng kết thúc tốt đẹp một loạt các mô hình. Mô hình của bạn sẽ không có thuộc tính is_checked (nghĩa là không có model.is_checked), chúng sẽ có các thuộc tính is_checked mặc dù (nghĩa là sẽ có model.get('is_checked')model.attributes.is_checked).

Bây giờ chúng ta có thể thấy nơi tất cả mọi thứ đi sai:

collection.chain().where({'is_checked':true}) 

Các mô hình không có is_checked tài sản. Đặc biệt, sẽ không có bất kỳ mô hình nào trong đó is_checkedtrue và mọi thứ sau khi where đang hoạt động với một mảng trống.

Bây giờ chúng ta biết mọi thứ diễn ra ở đâu, làm cách nào để khắc phục sự cố? Vâng, bạn có thể sử dụng filter thay vì where để bạn có thể dễ dàng giải nén các mô hình:

collection.chain() 
      .filter(function(m) { return m.get('is_checked') }) 
      .pluck('id') 
      .value(); 

Nhưng, mô hình của bạn không có id s nhưng như bạn không tạo cho họ id s và bạn thiên đường' t nói chuyện với một máy chủ để có được id s vì vậy bạn sẽ nhận được một mảng của undefined s trở lại. Nếu bạn thêm một số id s:

var collection = new App.OptionCollection([ 
    {id: 1, 'is_checked': true}, 
    {id: 2, 'is_checked': true}, 
    {id: 3, 'is_checked': false} 
]); 

sau đó bạn sẽ nhận được [1,2] mà bạn đang tìm kiếm.

Bản trình diễn: http://jsfiddle.net/ambiguous/kRmaD/

+0

Giải thích tuyệt vời. Cảm ơn! Trong môi trường thực tế của tôi, bộ sưu tập được lấy từ máy chủ, vì vậy chúng có id. – Bart

+0

'pluck' sẽ có cùng một vấn đề đối với hầu hết các thuộc tính vì nó không gọi' model.get() 'nhưng thay vào đó nhìn trực tiếp vào các thuộc tính của mô hình. 'id' là một thuộc tính đặc biệt được định nghĩa trên đối tượng để nó hoạt động nhưng các thuộc tính khác, chẳng hạn như' is_checked' sẽ trả về 'undefined'. – Spig

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