2012-02-22 6 views
19

Tôi có một ứng dụng xương sống với một cấu trúc nhìn trông giống như sau - lưu ý rằng tôi đã triển khai loại bỏ, các mô hình, các bộ sưu tập, vv cho ngắn gọn:Làm cách nào để tôi có thể "bong bóng" các sự kiện trong hệ thống phân cấp Backbone View?

NewsListView = Backbone.View.extend({ 

    el: $('li#newspane'), 

    // This is what I would like to be able to do 
    // events: { 'filtered': 'reset' } 

    initialize: function() { 
     _.bindAll(this); 
    }, 

    render: function() { 
    }, 

    reset: function(){ 
    } 

}); 

FilterView = Backbone.View.extend({ 

    el: $('li.filter'), 

    initialize: function() { 
    }, 

    render: function() { 
    }, 

    toggleFilter: function() { 
    } 

}); 

AllView = Backbone.View.extend({ 

    initialize: function() { 

     this.newsListView = new NewsListView(); 
     this.filterView = new FilterView(); 

    } 

}); 

Về cơ bản, bất cứ khi nào 's FilterViewtoggleFilter() chức năng được gọi là, tôi muốn kích hoạt một sự kiện có tên là filtered hoặc một cái gì đó tương tự mà sau đó bị bắt bởi NewsListView, sau đó gọi hàm reset() của nó. Không chuyển một tham chiếu của đối tượng NewsListView đến FilterView của tôi, tôi không chắc chắn cách gửi một sự kiện. Bất kỳ ý tưởng?

Trả lời

0

Vì vậy, tôi đã đưa ra một giải pháp - tạo một đối tượng mở rộng Backbone.Events và chuyển nó làm tham số cho nhiều chế độ xem. Điều này gần như cảm thấy như tin nhắn đi qua giữa các diễn viên, hoặc một cái gì đó. Dù sao - tôi đăng bài này như là một câu trả lời trong trường hợp bất cứ ai khác cần một giải pháp nhanh chóng, nhưng tôi sẽ không chấp nhận câu trả lời. Điều này cảm thấy hacky. Tôi vẫn muốn thấy một giải pháp tốt hơn.

NewsListView = Backbone.View.extend({ 
    el: $('li#newspane'), 

    // Too bad this doesn't work, it'd be really convenient 
    // events: { 'filtered': 'reset' } 

    initialize: function() { 
     _.bindAll(this); 
     // but at least this does 
     this.options.eventProxy.bind('filtered', this.reset); 
    }, 
    render: function() {}, 
    reset: function() {} 
}); 

FilterView = Backbone.View.extend({ 
    el: $('li.filter'), 

    initialize: function() {}, 
    render: function() {}, 
    toggleFilter: function() { 
     this.options.eventProxy.trigger('filtered'); 
    } 
}); 

AllView = Backbone.View.extend({ 
    initialize: function() { 
     var eventProxy = {}; 
     _.extend(eventProxy, Backbone.Events); 
     this.newsListView = new NewsListView({eventProxy: eventProxy}); 
     this.filterView = new FilterView({eventProxy: eventProxy}); 
    } 
}); 
0

Sự cố này có thể được giải quyết bằng cách sử dụng hack backbone.js nhỏ. Đơn giản chỉ cần sửa đổi Backbone.Events.trigger để thông qua các sự kiện để các this.parent

if this.parent != null 
3

Bạn có thể có thể làm điều này bằng cách sử dụng chức năng sẵn có của các sự kiện jquery và thuộc tính sự kiện xương sống.

Ví dụ, thay vì làm điều này từ bên trong subview của bạn:

this.trigger("yourevent", this); 

làm điều này thay vì:

this.$el.trigger("yourevent", this); 

Sau đó, trong bất kỳ quan điểm đó là một phụ huynh, ông bà, vv của xem con bạn , lắng nghe sự kiện trên $ el của chế độ xem đó bằng cách xác định thuộc tính trên đối tượng sự kiện của chế độ xem đó:

events:{ 
    "yourevent":"yourhandler" 
} 

và xác định các xử lý trên quan điểm cho rằng cũng như:.

yourhandler:function(subview) { 
} 

Vì vậy, theo cách này, một cái nhìn không cần phải biết về những gì quan điểm hậu duệ tồn tại, chỉ có các loại sự kiện đó là quan tâm đến việc Nếu xem có xuất xứ sự kiện bị phá hủy, không có gì cần phải thay đổi trên màn hình tổ tiên. Nếu khung nhìn tổ tiên bị hủy, Backbone sẽ tự động tách các trình xử lý.

Lưu ý: Tôi chưa thực sự cố gắng điều này, vì vậy có thể có một hình ảnh xác thực trong đó ở đâu đó.

+0

Điều này không hiệu quả đối với tôi. – anyaelise

+0

Cảm ơn bạn vì aha! chốc lát. –

0

Cách dễ nhất tôi đã tìm thấy để kích hoạt và nghe sự kiện là chỉ sử dụng chính đối tượng Backbone.Nó đã có những sự kiện chức năng trộn vào nó, vì vậy bạn chỉ có thể kích hoạt ví dụ:

Backbone.trigger('view:eventname',{extra_thing:whatever, thing2:whatever2}); 

sau đó, trong bất kỳ quan điểm xương sống khác trong ứng dụng của bạn, bạn có thể nghe cho sự kiện này ví dụ:

Backbone.on('view:eventname', function(passed_obj) { 
    console.log(passed_obj.extra_thing); 
}); 

Tôi không chắc chính xác lợi thế là không sử dụng đối tượng Backbone như trình xử lý sự kiện của bạn, và thay vào đó tạo một đối tượng riêng để thực hiện, nhưng đối với công việc nhanh chóng và bẩn, công việc trên tốt. HTH!

LƯU Ý: một bất lợi cho điều này là mọi người nghe sẽ "nghe" mọi sự kiện được kích hoạt theo cách này. Bạn không chắc chắn O lớn là gì, nhưng làm việc cẩn thận để không quá tải quan điểm của bạn với rất nhiều công cụ này. Một lần nữa: điều này là nhanh chóng và bẩn! :)