2012-03-03 17 views
8

मेरे पास DashboardView नामक एक दृश्य है जो एकाधिक WidgetView एस को तुरंत चालू करता है। प्रत्येक विजेट को अपनी खुद की घटना बाइंडिंग की आवश्यकता होती है। जहां तक ​​मैं बता सकता हूँ, इन बाइंडिंग जब दृश्य प्रदान की गई और माता पिता को देखने के लिए जोड़ा जाता है, यानी खो जाना:Backbone.js में ईवेंट नेस्टेड विचार

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) 

यह इस तरह से कर रहा, विजेट का .config तत्व पर क्लिक ईवेंट अब खो रहे हैं । क्या बच्चे के दृश्य पर ईवेंट हैंडलर सही ढंग से चैनल किए गए हैं, यह सुनिश्चित करते हुए नेस्टेड दृश्यों को अभिभावक में मिश्रित करने का एक बेहतर तरीका है?

इस समस्या को मैंने देखा है एक समाधान this article में आता है। यह सही दिखता है, लेकिन अगर मैं इसे हल करने का एक और शानदार तरीका हूं तो मैं उत्सुक हूं।

उत्तर

10

इस प्रयास करें:

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 

तो, विचार यह है:

(1) WidgetView के render विधि के अंदर, आप पॉप्युलेट @el (देखने का मूल तत्व) के साथ अपने मॉडल टेम्पलेट के माध्यम से डेटा। (और ध्यान दें कि किस मैं टेम्पलेट संकलन केवल एक बार - प्रत्येक ऑपरेशन प्रस्तुत करना पर टेम्पलेट संकलित करने के लिए कोई जरूरत नहीं है।)

(2) DashboardView के अंदर, आप संलग्न विजेट के मूल तत्व - @el - डोम के लिए ।

बात यह है कि दृश्य की घटनाएं इसके मूल तत्व - @el पर प्रतिनिधि हैं। इसलिए, आप मूल तत्व के साथ स्पष्ट रूप से काम करना चाहते हैं: render के अंदर, आप इसे पॉप्युलेट करते हैं, और उसके बाद आप इसे DOM में जोड़ते हैं।

+0

यह वही है जो मैं ढूंढ रहा था। धन्यवाद! – picardo

+4

आप ['(w) =>'] (http://coffeescript.org/#fat_arrow) का उपयोग कर 'संदर्भ' सामग्री से बच सकते हैं। और '@ संग्रह' अंडरस्कोर होना चाहिए-ified पहले से ही '@collection.each (w) =>' एक और विकल्प है। –

+0

@ एमयू कूल ':) 'वसा तीर के बारे में नहीं पता था। –

1

आपकी समस्या यह है कि delegateEvents आपके विचार के लिए एक एकल, गैर-परिवर्तनकारी तत्व की अपेक्षा करता है। चूंकि फ़ंक्शन हर बार एक नया तत्व बनाता है, delegateEvents द्वारा बनाई गई बाइंडिंग को कभी भी निकाल दिया नहीं जाता है जब आप render द्वारा उत्पन्न तत्व पर क्लिक करते हैं।

सौभाग्य से बैकबोन का वर्तमान संस्करण setElement method प्रदान करता है जो आपके द्वारा प्रदान किए गए तर्क के साथ आपके तत्व को पुन: असाइन करेगा, और फिर यह स्वचालित रूप से delegateEvents पर कॉल करेगा।

+0

एक बात मुझे स्पष्ट करनी चाहिए कि मेरे पास एक डैशबोर्ड में कई विजेट्स को तुरंत चालू किया गया है। तो तत्व को पुन: असाइन करना बिल्कुल वैसा ही नहीं है जो मुझे चाहिए, मुझे लगता है। – picardo

संबंधित मुद्दे