2012-03-27 29 views
14

Với đoạn mã sau:Tại sao mô hình Backbone của tôi hasChanged() luôn trả về false?

var m = new Backbone.Model({ 
    name: 'joshua' 
}); 

m.set('name', 'something else'); 

Nếu bây giờ tôi gọi m.hasChanged() hoặc m.hasChanged('name') tôi nhận được false. Tại sao? Sự hiểu biết của tôi là cả hai điều này nên trả về true.

m.changedAttributes() cũng trả về false.

Đây là một fiddle minh họa những gì tôi đang làm, và mong đợi: http://jsfiddle.net/9cvVv/88/

EDIT: Có vẻ như rằng trừ khi bạn vượt qua { silent: true; } với phương pháp set() sau đó nó sẽ cháy sự kiện change trên mô hình của bạn mà xóa các số changedAttributes(), v.v. Về cơ bản, các thuộc tính này chỉ theo dõi các thay đổi kể từ lần cuối cùng sự kiện change được kích hoạt.

Tôi đã đọc điều đó trong tài liệu nhưng không thực sự hiểu nó lúc đầu.

Điều này dường như không hữu ích đối với tôi. Tôi sẽ đánh giá cao bất kỳ lời giải thích về lý do tại sao điều này hoạt động theo cách của nó và cách tốt nhất để đạt được kết quả tôi muốn. (Đi qua khoảng {silent: true; } và từ bỏ việc sử dụng các sự kiện change có vẻ như một sự lãng phí.)

Trả lời

15

Trừ khi bạn vượt qua { silent: true; } với phương pháp set() sau đó nó sẽ cháy sự kiện change trên mô hình của bạn mà gạt bỏ cái changedAttributes(), vv Về cơ bản những các thuộc tính chỉ theo dõi các thay đổi kể từ lần cuối cùng sự kiện change được kích hoạt.

Vì vậy, câu trả lời là để gọi đây là thay vì:

m.set('name', 'something else', {silent: true}) 
+0

Ah ha. Tôi đã tạo một phương thức 'save()' cho các bộ sưu tập gửi một loạt các mô hình và trả về. Đã tự hỏi tại sao hasChanged() dường như không làm gì cả. :-) Cảm ơn! – jmk2142

+0

Điều này không còn đúng trong các phiên bản mới hơn của Backbone; xem câu trả lời của tôi – pimlottc

+0

Lưu ngày của tôi với xương sống 0.9.2 ... – gor181

-7

Model.set() mất một thuộc tính hash như là đối số đầu tiên. Hãy thử m.set({'name': 'something else'});. Làm m.set('name', 'something') không đặt 'tên', vì vậy nó không bao giờ kích hoạt sự kiện change và cuộc gọi của bạn tới hasChanged() trả về false. Bạn luôn có thể kiểm tra giá trị hiện tại của băm thuộc tính bằng cách đăng xuất m.attributes - mặc dù việc truy cập và thao tác trực tiếp không được khuyến nghị vì không có sự kiện thay đổi nào kích hoạt theo cách đó.

+1

Sai. 'Model.set()' hỗ trợ cả băm và một thuộc tính đơn như tôi đang sử dụng. Thuộc tính đang được thiết lập, như bạn có thể thấy trong [fiddle hơi mở rộng này] (http://jsfiddle.net/H2raK/1/). Điều này cũng được minh họa [trong tài liệu Backbone.js] (http://backbonejs.org/#Model-set). – joshuapoehls

+0

Xin lỗi về điều đó, nên đã đọc kỹ hơn. Chính xác là bạn đang cố gắng làm gì? Bạn chỉ có thể liên kết với sự kiện 'change' của mô hình. Bằng cách đó bạn có thể kiểm tra các thuộc tính cụ thể cho thay đổi w/'hasChanged (attr)' (để xem bạn có cần cập nhật một phần nào đó của khung nhìn) hay không. Tôi đã chỉnh sửa [fiddle] của bạn (http://jsfiddle.net/H2raK/4/) để minh họa điều này. – meirish

+0

Về cơ bản tôi đang cố gắng để có được danh sách các thuộc tính đã thay đổi kể từ khi mô hình được lưu. Bây giờ tôi đang đi qua '{silent: true}' xung quanh và sau đó kiểm tra 'changedAttributes()'. Điều này làm việc chính xác như tôi cần, tôi dự kiến ​​Backbone sẽ hoạt động giống như cờ 'isDirty' truyền thống trong một mô hình dữ liệu. – joshuapoehls

11

Bài đăng này được đặt trước về hành vi trước đó của các phiên bản cũ của Backbone. hasChangedhiện tại (as of 0.9.10) luôn trả về true sau khi set(..) được gọi. Cờ silent không còn hiệu lực.

Điều này được che giấu nhầm lẫn trong jsfiddle được liên kết trong câu hỏi sử dụng bản sao backbone.js được CDN lưu trữ luôn sử dụng phiên bản mới nhất. Dưới đây là một số jsfiddles cập nhật cho thấy sự thay đổi trong hành vi:

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