2012-04-16 21 views
5

मैं एक दोस्त सूची उर्फ ​​रोस्टर को लागू करने के लिए backbone.js का उपयोग कर रहा हूं।Backbone.js: संग्रह से किसी आइटम को हटाएं

Slx.Roster.Views.RosterEntry = Backbone.View.extend({ 
    tagName: "li", 
    className : "rosterEntry clearfix", 
    templateSelector: '#rosterEntryTemplate', 

    initialize: function() { 
     _.bindAll(this, 'render'); 
     this.model.bind('change', this.render); 
     this.model.bind('remove', this.remove); 
     this.template = _.template($("#rosterEntryTemplate").html()); 
    }, 

    remove: function() { 
     debug.log("Called remove event on model"); 
     $(this.el).remove(); 
    }, 
    render: function() { 
     var renderedContent = this.template(this.model.toJSON()); 
     this.id = this.model.Id; 
     $(this.el).attr('id', "friendid-" + this.model.get("id")).html(renderedContent); 
     return this; 
    } 
}); 

    Slx.Roster.Views.Roster = Backbone.View.extend({ 
     el: "div#roster-container", 
     initialize: function() { 
      _.bindAll(this, 'render', 'add', 'remove'); 
      this.template = _.template($("#rosterTemplate").html()); 
      this.collection.bind('reset', this.render); 
      this.collection.bind('add', this.add); 
      this.collection.bind('remove', this.remove); 
     }, 
     add: function (rosterEntry) { 
      var view = new Slx.Roster.Views.RosterEntry(
       { 
        model: rosterEntry 
       }); 
      $(this.el).append(view.render().el); 
     }, 
     remove: function (model) { // if I ommit this then the whole collection is removed!! 
      debug.log("called remomve on collection"); 
     }, 
     render: function() { 
      var $rosterEntries, collection = this.collection; 

      $(this.el).html(this.template({})); 
      $rosterEntries = this.$('#friend-list'); 

      _.each(collection.models, function (model) { 
       var rosterEntryView = new Slx.Roster.Views.RosterEntry({ 
        model: model, 
        collection: collection 
       }); 

       $(this.el).find("ul#friend-list").append(rosterEntryView.render().el); 
      }, this); 

      return this; 
     } 
    }) 

मैं अब Firebug कंसोल का उपयोग कर के लिए परीक्षण कर रहा हूँ और क्रियान्वित करते हुए ठीक रोस्टर पॉप्युलेट कर सकते हैं निम्नलिखित:

collection = new Slx.Roster.Collection 
view = new Slx.Roster.Views.Roster({collection:collection}) 
collection.fetch() 

रोस्टर के संग्रह और व्यक्तिगत rosterEntry के लिए मेरे रीढ़ दृश्य इस प्रकार हैं एक संग्रह को जोड़ना भी ठीक काम करता है, Firebug कंसोल में निम्नलिखित को निष्पादित करके:

collection.add(new Slx.Roster.Model({username:"mickeymouse"})

और रोस्टर में नया rosterEntry जोड़ा गया है।

मेरी समस्या यह है कि collection.remove(5) इन-मेमोरी संग्रह से हटाता है, लेकिन DOM को अपडेट करने के लिए कुछ भी नहीं करता है।

आश्चर्यजनक रूप से, अगर मैं रोस्टर व्यू से remove() फ़ंक्शन को छोड़ देता हूं, तो रोस्टर में सभी प्रविष्टियां हटा दी जाती हैं। यदि मैं इस विधि को इसमें कुछ भी नहीं जोड़ता लेकिन एक कंसोल लॉग करता हूं, तो रोस्टर और RosterEntry दोनों दृश्यों पर निकालने का तरीका कहा जाता है - हालांकि मुझे यकीन नहीं है कि वे क्यों हैं लेकिन वे आदेश से बाहर हैं!

TypeError: this.$el is undefined 
this.$el.remove(); 

क्या मैं गलत कर रहा हूँ:

["Called remove event on model"] 
["called remomve on collection"] 

अगर मैं RosterEntry मॉडल से निकालने के समारोह को हटाना मैं इस त्रुटि मिलती है? जब संग्रह से हटा दिया जाता है तो मैं डीओएम से तत्व को कैसे हटा सकता हूं?

उत्तर

2

मुझे लगता है कि आप हर घटना बाँध परिभाषा context साथ एक समस्या है।

कोशिश इसे बदलने के लिए:

this.model.bind('remove', this.remove); 

इस के लिए:

this.model.bind('remove', this.remove, this); 

मैं तुम्हें bindAll के साथ इस का समाधान करने की कोशिश की है, लेकिन bindAll के साथ सूचीबद्ध तरीकों के लिए हर कॉल लपेटकर है वास्तविक वस्तु का संदर्भ, लेकिन यदि आप अन्य ऑब्जेक्ट पर समान विधि को कॉल कर रहे हैं तो यह कुछ भी नहीं कर सकता है :)।

मैं है और अधिक पढ़ने .. bindAll तरह लग रहा है और bind आदेश के तीसरे परमाटर बिल्कुल भी ऐसा ही अपडेट किया गया। तो शायद आप एक या दूसरे का उपयोग कर सकते हैं।

क्योंकि है काम कर model.remove में bindAll है, क्योंकि आप _.bindAll(this, 'render') लाइन को जोड़ने के लिए, अपने कोड में देखने के लिए भूल गया नहीं। और मेरे सुझाव ने इसे ठीक कर दिया क्योंकि जैसा कि मैंने कहा है कि दोनों दृष्टिकोण समान हैं।

यह सब क्या कर रहा है आश्वस्त है कि सूचीबद्ध तरीके (एक मामले में render, remove, ... या this.remove अन्य में) करने के लिए कॉल करने वाले हैं वास्तविक वस्तु के लिए एक संदर्भ के रूप में interpretate this। यह बेवकूफ लग सकता है लेकिन this जेएस में बहुत अस्थिर है।

चिंता न करें अगर आप अभी भी this चीज़ से उलझन में हैं, तो मैं इसे लंबे समय से और not completely cofindent से निपट रहा हूं।

शायद essais like this हमारी मदद कर सकता है।

+1

आपका क्या मतलब है कि मुझे हर शाम बांध परिभाषा के साथ कोई समस्या है? यकीन नहीं है कि मैं वास्तव में समझता हूं कि बाइंडल आपके साथ ईमानदार होने के लिए क्या है। मैंने सोचा कि सभी घटनाओं को बाइंडल में जोड़ा जाना था। – reach4thelasers

+0

बाइंड फ़ंक्शन पर तीसरा पैरामीटर क्या दर्शाता है? – reach4thelasers

+0

यह काम किया! धन्यवाद! मुझे लगता है कि मैंने एक और स्टैक ओवरफ्लो पोस्ट पढ़कर क्या किया है, लेकिन काम क्यों नहीं किया? ऐसा लगता है कि यह वही काम करता है .... मुझे संग्रह बंड स्टेटमेंट पर अतिरिक्त 'यह' क्यों नहीं चाहिए? – reach4thelasers

-1

दोनों विचारों पर निकालने के तरीके शायद इसलिए कहा जा रहा है क्योंकि आप मॉडल और संग्रह दोनों को हटाने के लिए बाध्य हैं।

RosterEntry में:

this.model.bind('remove', this.remove); 

रोस्टर में:

this.collection.bind('remove', this.remove); 
+0

क्या यह मुझे पहले से ही नहीं मिला है? – reach4thelasers

0

क्या आपने निम्न का प्रयास किया है?

this.listenTo(this.model, "remove", this.remove); 

ऐसा लगता है कि मेरे लिए काम करता है और मुझे यह पसंद है कि यह थोड़ा बेहतर तरीके से पढ़ता है।

Link to Backbone doc

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