2012-04-19 24 views
8

Tôi đang làm việc với ứng dụng ví dụ Todos bundled with the latest version of Backbone (0.9.2) trong khi tìm hiểu về Backbone.js. Câu hỏi của tôi là, tại sao ứng dụng được thiết kế để kích hoạt sự kiện kết xuất hai lần khi thêm mô hình vào bộ sưu tập Todos?Các vụ cháy Backbone.js hiển thị hai lần trên bộ sưu tập thêm

Nếu tôi đặt dòng này trong chức năng làm cho của TodoView: "Rendering"

// Re-render the titles of the todo item. 
render: function() { 
    console.log("Rendering!"); 
    this.$el.html(this.template(this.model.toJSON())); 

Sau đó, xuất hiện hai lần trong bảng điều khiển. Tôi hiểu điều này là bởi vì quan điểm liên kết với sự kiện thay đổi của mô hình để của view render:

initialize: function() { 
    this.model.bind('change', this.render, this); 

Và làm được gọi trong addOne, được ràng buộc với Todos add sự kiện:

addOne: function(todo) { 
    var view = new TodoView({model: todo}); 
    this.$("#todo-list").append(view.render().el); 
}, 

Nhưng là thực hành tiêu chuẩn thiết kế dựng hình kép này? Có vẻ như khung nhìn nên được hiển thị khi tạo (hoặc truy cập vào DOM), và sau đó lại nếu mô hình cơ bản thay đổi. Trong trường hợp này, không có gì đang được thay đổi, nhưng kết xuất được gọi hai lần.

Một lần nữa, tôi chỉ học về xương sống, vì vậy tôi có thể có một sự hiểu lầm cơ bản dẫn đến sự nhầm lẫn của tôi.

Trả lời

5

Hm, có giao diện nhanh. Bạn đúng rằng điều này xảy ra, và không có nó không phải là thực hành tiêu chuẩn. Lý do hơi mơ hồ, do đó hãy chịu theo tôi;)

Ứng dụng cần làm đang sử dụng lưu trữ cục bộ. Khi bạn thử thêm một mục mới trong ứng dụng, nó gọi:

createOnEnter: function(e) { 
    if (e.keyCode != 13) return; 
    if (!this.input.val()) return; 

    Todos.create({title: this.input.val()}); 
    this.input.val(''); 
}, 

Lưu ý Todos.create. Thông thường, create sẽ thêm một mô hình vào bộ sưu tập cũng như lưu nó trên máy chủ. Do đó, sự kiện add sẽ được kích hoạt. Nó xảy ra dù rằng xương sống-localStorage nào sau đây trên create:

create: function(model) { 
    if (!model.id) model.set(model.idAttribute, guid()); 
    this.data[model.id] = model; 
    this.save(); 
    return model; 
}, 

Thông báo các model.set để cung cấp cho các mô hình một id. Đây là những gì kích hoạt sự kiện (2) change (thứ hai).

Bạn có thể ngăn chặn điều này xảy ra bằng cách thay đổi tạo ra để làm:

if (!model.id) model.id = guid();

+1

nice catch! .. bạn cũng có thể sử dụng '{silent: true}' để tránh các sự kiện kích hoạt. – fguillen

+1

Bạn nói đúng, đó là lý do sự kiện thay đổi đang được kích hoạt. Tuy nhiên, việc thay đổi mã theo cách bạn đề xuất dừng sự kiện nhưng cũng phá vỡ chức năng (Tôi không còn có thể xóa các mục) nữa. Rõ ràng điều này không quan trọng nhiều trong việc trả lời câu hỏi của tôi, nhưng chỉ trong trường hợp ai đó trong tương lai đọc điều này, tôi muốn chỉ ra điều đó. – jcady

+0

Xóa các mục _permanently_ nghĩa là. Sau khi xóa, nếu tôi làm mới chúng vẫn tồn tại. – jcady

1

trả lại không nên xảy ra.

Cố gắng gỡ lỗi nhiều hơn một chút. Cố gắng ràng buộc kiện thay đổi đến một phương pháp wrapper như:

initialize: function(){ 
    this.model.bind("change", this.renderWrapper, this); 
}, 

renderWrapper: function(){ 
    console.log("in the renderWrapper"); 
    this.render(); 
} 

Để chắc chắn thứ hai render() đã được thực hiện cho thay đổi sự kiện ràng buộc và không vì lý do khác.

+0

Bạn nói đúng. Tôi cần phải lưu ý trong câu hỏi của tôi rằng tôi ban đầu thu hẹp này bằng cách đặt 'console.log ('Thay đổi!')' Thay cho 'this.render()'. Do đó tôi đã chắc chắn sự kiện thay đổi đã được bắn. – jcady

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