2013-01-25 14 views
21

मैं backbone.js सीख रहा हूँ, और इस पर उलझन में: http://arturadib.com/hello-backbonejs/मुझे Backbone.js में _.bindAll() का उपयोग करने की आवश्यकता कब होगी?

के रूप में आप पहले उदाहरण में देख सकते हैं (1.js):

(function($){ 
    var ListView = Backbone.View.extend({  
    el: $('body'), // attaches `this.el` to an existing element. 

    initialize: function(){ 
     _.bindAll(this, 'render'); // fixes loss of context for 'this' within methods 

     this.render(); // not all views are self-rendering. This one is. 
    }, 

    render: function(){ 
     $(this.el).append("<ul> <li>hello world</li> </ul>"); 
    } 
    }); 

    var listView = new ListView();  
})(jQuery); 

लेकिन मैं ट्यूटोरियल अनुसरण कर रही हूं अगर मैं वाक्य को टिप्पणी करता हूं: _.bindAll(this, 'render');, यह अभी भी काम करेगा। मैंने Google में खोज की है और किसी ने कहा है कि विधि bindAll() आवश्यक है क्योंकि मैंने अपना संदर्भ बदल दिया है, this.render की कॉलिंग अनुपलब्ध हो सकती है। मुझे "संदर्भ" पर उलझन में लग रहा है। और कॉलिंग (this.render) अनुपलब्ध होने पर भी कोई मुझे समझा सकता है?

उत्तर

26

उदाहरण आप _.bindAll(this, 'render'); दिया है के लिए आवश्यक नहीं है, लेकिन यदि आप कॉलबैक कार्यों जहां this संभवतः कुछ और के संदर्भ में बदला जा सकता है, तो _bindAll() काम हो सकता है।

उदाहरण के लिए:

initialize: function(){ 
    _.bindAll(this, 'render', 'clickFunc'); 
}, 
events: { 
    'click .someElement': 'clickFunc' 
}, 
clickFunc: function(e) { 
    /** If you remove the clickFunc from the list of events in bindAll, 
      'this' will refer to the element that invoked the event. 

     Adding the clickFunc event in the _.bindAll, ensures that 'this' stays 
      as the view. 
    */ 
    this /** <-- our focal point */ 
} 
+9

कुछ भी बैकबोन, एफवाईआई द्वारा स्वचालित रूप से बाध्य है। –

+0

बहुत अच्छी व्याख्या, महान काम – M3ghana

2

इस उदाहरण में आप _.bindAll की जरूरत नहीं है, लेकिन मान लीजिए कि आपके विचार के लिए एक विधि है कि एक rerender का कारण बनता है और आप कुछ इस तरह करते हैं:

.., 
myMethod: function() { 
    this.$('.someselector').change(this.render); 
}, 

आप render के लिए _.bindAll नहीं है , आपका संदर्भ बंद हो जाएगा।

10
  • किसी भी आपके विचार की घटनाओं में संपत्ति मूल्यों के रूप में सूचीबद्ध तरीकों हैश स्वचालित रूप से रीढ़ की हड्डी से आप के लिए बाध्य कर रहे हैं
  • अपने ध्यान में रखते हुए किसी भी तरीके कि आप मैन्युअल रूप से मॉडल या संग्रहण से ईवेंट हैंडलर्स के रूप में उपयोग मैन्युअल bindAll के माध्यम से बाध्य किया जाना चाहिए
    • या जब आप रजिस्टर बाध्यकारी
    • या आप उपयोग कर सकते EMCA 5 के function.bind ही परिणाम
  • पाने के लिए यदि आप कोई संदर्भ प्रदान कर सकते हैं

टुकड़ा:

events: { 
    'click .win': 'win', 
    'click .lose': 'lose' 
}, 
initialize: function() { 
    //win and lose are automatically bound for you 
    //because they are in the events property 

    //refresh must be manually bound 
    this.model.on('change', this.refresh); 

    //which you can do ECMA5 style if you like 
    this.model.on('change', this.refresh.bind(this)); 

    //OR you can provide a context backbone style 
    this.model.on('change:foo', this.fooChange, this); 

    //However, since you pretty much never want an unbound function 
    //in a view, you can just stick this in all your initialize methods 
    //and call it done 
    //Note this will bind all functions in your view class if you don't 
    //pass specific method names. I recommend this form. 
    _.bindAll(this); 
}, 
win: function() {...}, 
lose: function() {...}, 
refresh: function() {...}, 
fooChange: function() {...} 

... OOOOORRRR सिर्फ CoffeeScript और वसा तीर का उपयोग करें और भाषा के स्तर पर सफाई से इस का समाधान।

+2

मुझे और _.bindAll (यह) भी पसंद है, लेकिन अंडरस्कोर इसकी अनुशंसा नहीं करता है, और यह 1.5.0 संस्करण के बाद से और समर्थित नहीं होगा। चेंजलॉग में आप पढ़ सकते हैं: _.bindAll को कॉल करने की क्षमता को बिना किसी विधि नाम तर्क के हटा दिया गया है। उन विधियों के नामों को सफेद सूची में रखना हमेशा बहुत बुद्धिमान होता है जिन्हें आप बांधना चाहते हैं। http://underscorejs.org/#changelog मुझे लगता है कि यह एक त्रुटि है। यह मुझे बनाए रखने के लिए और अधिक कठिन होगा। – ccsakuweb

+0

@ccsakuweb मैं वर्तमान में एक वेब इंटरफ़ेस पर काम कर रहा हूं जहां मैं बैकबोन का भारी उपयोग करता हूं। इस प्रोजेक्ट में वर्तमान में मेरे पास '_.bindAll' पर * एक * कॉल है, और' _.bind' के लिए कोई भी नहीं है। इसके बजाय मैं मॉडल घटनाओं को सुनने के लिए 'this.listenTo' का उपयोग करता हूं,' घटनाओं के लिए 'ईवेंट' हैश इत्यादि, और इसके बजाय संदर्भ प्रदान करता हूं। एक '_.bindAll' कॉल पृष्ठभूमि autorefresher की 'रन' विधि के लिए है, जो' setTimeout (this.run, period) 'कहता है जो' रन 'विधि को इसके संदर्भ को खोने का कारण बनता है। इस बिंदु पर बाकी सब कुछ '_.bindAll' के बिना पूरी तरह से प्रबंधित किया जा सकता है। घटनाओं में –

2

क्या _.bindAllunderscore.js offical docs से करता है पर विशेष ध्यान दें करने देता है।

_.bindAll = function(obj) { 
    var i, length = arguments.length, key; 
    if (length <= 1) throw new Error('bindAll must be passed function names'); 
    for (i = 1; i < length; i++) { 
     key = arguments[i]; 
     obj[key] = _.bind(obj[key], obj); 
    } 
    return obj; 
    }; 

यह क्या करता है अपने सभी कार्यों को अपने सही संदर्भ में स्वचालित रूप से बांधना है। (जहां अपने कार्य के बजाय घोषित किया जाता है लागू की तुलना में।

मैं व्यक्तिगत रूप से लगता है कि यह अपने events, या डोम कार्रवाई श्रोताओं बाध्य करने के लिए Backbone.js के पुराने संस्करण के लिए एक सम्मेलन था। के बाद से नए संस्करणों बैकबोन स्वचालित रूप से बाँध और events में अनबाइंड श्रोताओं View ।खोज Binding "this"here

मुझे उम्मीद है कि इससे मदद मिलती है।

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