2012-03-03 32 views
8

Tôi có chế độ xem được gọi là DashboardView để khởi tạo nhiều WidgetView s. Mỗi widget cần phải có sự ràng buộc sự kiện riêng của nó. Cho đến nay như tôi có thể nói, những cam kết ràng buộc bị lạc khi xem là ra và thêm vào xem cha mẹ, ví dụ:Sự kiện trong Backbone.js các chế độ xem lồng nhau

class DashboardView extends Backbone.View 
    constructor: -> 
    context = @ 
    _.each @collection, (w)-> 
     dv = new app.WidgetView(model: w) 
     context.$el.append(dv.render()) 

class WidgetView extends Backbone.View 
    events: 
    "click .config" : "config_widget" 

    render: -> 
     _.template($("#widget-template").html(), @model) 

Làm theo cách này, những sự kiện nhấp chuột vào các yếu tố .config của widget được bây giờ bị mất . Có cách nào tốt hơn để trộn các khung nhìn lồng nhau vào cha mẹ trong khi đảm bảo rằng các trình xử lý sự kiện trên chế độ xem con được chuyển đúng không?

Một giải pháp mà tôi đã gặp phải cho sự cố này có trong số this article. Điều này có vẻ đúng, nhưng tôi tò mò nếu có một cách thanh lịch hơn để giải quyết điều này.

Trả lời

10

Hãy thử điều này:

class DashboardView extends Backbone.View 
    constructor: -> 
    @collection.each (w) => 
     dv = new app.WidgetView(model: w) 
     @$el.append dv.render().el // Append widget's @el explicitly 

class WidgetView extends Backbone.View 
    tagName: 'div' // or whatever your view's root element is 

    template: _.template $("#widget-template").html() // pre-compile template 

    events: 
    "click .config": "config_widget" 

    render: -> 
    @$el.html @template @model.toJSON() // append template to @el 
    return this // return view 

Vì vậy, ý tưởng là thế này:

(1) Bên render phương pháp 's WidgetView, bạn cư @el (phần tử gốc của view) với mô hình của nó của dữ liệu qua mẫu. (Và nhận thấy làm thế nào tôi biên dịch mẫu chỉ một lần - không có nhu cầu để biên dịch các mẫu trên mỗi kết xuất hoạt động.)

(2) Bên trong DashboardView, bạn nối thêm phần tử gốc của widget - @el - vào DOM .

Vấn đề là các sự kiện của lượt xem được ủy quyền cho phần tử gốc của nó - @el. Do đó, bạn muốn làm việc với phần tử gốc một cách rõ ràng: bên trong render, bạn điền vào nó, và sau đó bạn thêm nó vào DOM.

+0

Đây chính xác là những gì tôi đang tìm kiếm. Cảm ơn bạn! – picardo

+4

Bạn có thể tránh các nội dung 'bối cảnh' bằng cách sử dụng [' (w) => '] (http://coffeescript.org/#fat_arrow). Và '@ collection' nên là Underscore-ified, vì vậy '@collection.each (w) =>' là một tùy chọn khác. –

+0

@mu Cool ':)' Không biết về mũi tên béo. –

1

Vấn đề của bạn là delegateEvents dự kiến ​​một yếu tố duy nhất, không thay đổi cho chế độ xem của bạn. Vì hàm render của bạn tạo thành phần tử mới mỗi lần, các liên kết được thực hiện bởi delegateEvents sẽ không bao giờ được kích hoạt khi bạn nhấp vào phần tử được tạo bởi render.

May mắn phiên bản hiện tại của Backbone cung cấp setElement method sẽ gán lại yếu tố của bạn với đối số bạn cung cấp và sau đó nó sẽ tự động gọi delegateEvents.

+0

Một điều tôi nên làm rõ ràng là tôi có nhiều tiện ích được khởi tạo trong một trang tổng quan. Vì vậy, phân công lại các yếu tố không phải là chính xác những gì tôi muốn, tôi nghĩ. – picardo

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