2012-07-24 70 views
0

碰到問題與使用Backbone.js的和underscore.js結合這this.collection.add

this.collection.bind('add',appendItem) 

this.collection.bind('add',appendSet) 

appendItem一個教程內的定義的函數backbone.js視圖收集視圖。相同的appendSet問題是,我想通過嵌套模型來擴展教程,但是當我添加一個項目時,如果我使用上面的行,我已經將appendItem和appendSet綁定到add函數,所以add函數獲得不知道這應該是什麼。

(什麼綁定快速提醒作用:http://underscorejs.org/#bind

那我怎麼還在用

this.collection.add(thisItem) 

,仍然避免綁定問題。 簡而言之:有沒有辦法調用this.collection.add(thisItem)並告訴add函數關鍵字'this'應該引用appendItem而不使用bind函數?

如果有要求,我可以包括我的代碼,但我認爲它有點長,笨重,可能無用。

編輯:

我的代碼的邏輯是這樣的。項目是具有多個屬性和與其相關的一組集合的模型。我只是按照教程,他得到這些對象呈現的方式是他使用this.collection.bind('add',appendItem),以便當你調用this.collection.add時,appendItem將被調用。下面是appendItem代碼:

appendItem: function(item){ 
     alert("append exercise called in allExerciseview"); 
     var itemView=new ItemView({ 
     model: Item 
     }); 
     $('ul',this.el).append(itemView.renderItem().el); 
     } 

我找不到的源代碼this.collection.add,但我假設該函數具有這種指appendItem調用appendItem功能。 總之:的原因是此代碼:

this.collection.bind('add',appendItem) 

使得它如此,當你調用

this.collection.add(thisItem) 

它也運行

thisItem.appendItem() 

解除綁定他們,只是在運行此。 collection.add(thisItem),然後單獨運行thisItem.appendItem()不適合我。

我的示例代碼:

(function($){ 
    Backbone.sync = function(method, model, success, error) { 
     success(); 
    }; 

    var Set = Backbone.Model.extend({ 
     defaults: { 
      SetName:"Set " 
      //more properties... 
     }, 
     initialize: function(){ 
      alert("you've created a new set"); 
      this.bind("error",function(model,error){ 
       alert(error); 
      }); 
     } 
    }); 

    var SetCollection = Backbone.Collection.extend({ 
     model:Set 
    }); 

    var SetView = Backbone.View.extend({ 
     events: { 
      'click button.deleteSet': 'removeSet' 
     }, 
     initialize: function(){ 
      alert('initialize called in setview'); 
      _.bindAll(this,'renderSet', 'unrenderSet', 'removeSet'); 
     /*this.model.bind('change',this.renderSet); 
     this.model.bind('remove',this.unrender); Not sure if I should do this*/ 
      return this; //apparently for chainable calls  
     }, 
     renderSet: function(){ 
      alert('renderset called in setview'); 
      $(this.el).html('a set template'); //add button after so you can test delete 
      return this; 
     }, 
     unrenderSet: function(){ 
      alert('unrenderset called in setview'); 
      $(this.el).remove(); 
     }, 
     removeSet: function(){ 
      alert('removeset called in setview'); 
      this.model.destroy(); 
     } 
    }); 

    var AllSetView = Backbone.View.extend({ 
     el: $('body'), //el attaches to existing element <-- what does this mean? 
     events: { 
      'click button#addSetButton': 'addSet' 
     }, 
     initialize: function(){ 
      alert('initialize called in allsetview'); 
      _.bindAll(this,'renderAllSet', 'addSet', 'appendSet'); 
      this.collection = new SetCollection(); 
      this.collection.bind('add', this.appendSet); // Problem here... 
      this.counter = 0; 
      this.renderAllSet(); 
     }, 
     renderAllSet: function(){ 
      alert('renderallset called in allsetview'); 
      var self = this; 
      $(this.el).append('<button id="addSetButton"> Add Set </button>'); 
      $(this.el).append('<ul></ul>'); 
      _(this.collection.models).each(function(set){ //in case collection is not empty 
       self.appendSet(set); 
      },this); 
     }, 
     addSet: function(){ 
      alert('addSet called in allsetview'); 
      this.counter++; 
      var thisSet = new Set(); 
      thisSet.set({SetName:thisSet.get('SetName')+this.counter}); 
      this.collection.add(thisSet); //add is a function defined for the collection 
     }, 
     appendSet: function(item){ 
      alert("append set called in allsetview"); 
      var setView = new SetView({ 
       model: Set //DO NOT CAPITALIZE!!!... or do capitalize?... ack 
      }); 
      $('ul',this.el).append(setView.renderSet().el); 
     } 
    }); 

    var allsetview = new AllSetView(); //for testing 

    var Item = Backbone.Model.extend({ 
     defaults: { 
      ItemName: 'Enter an Item' 
      //more properties 
     }, 
     initialize: function(){ 
      alert('youve created a new item'); 
      var set1 = new Set(); 
      var setCollection = new SetCollection([set1]); 
      this.set({sets:setCollection}); 
      this.bind("error",function(model,error){ 
       alert(error); 
      }); 
     } 
    }); 

    var ItemCollection = Backbone.Collection.extend({ 
     model:Item 
    }); 

    var ItemView = Backbone.View.extend({ 
     events: { 
      'click button.deleteItem': 'removeItem' 
     }, 
     initialize: function(){ 
      alert('initialize called in itemview'); 
      _.bindAll(this,'renderItem', 'unrenderItem', 'removeItem'); 
      //this.model.bind('change',this.renderItem); 
      //this.model.bind('remove',this.unrender); Not sure if I should do this 
      return this; //apparently for chainable calls  
     }, 
     renderItem: function(){ 
      alert('renderitem called in Itemview'); 
      $(this.el).html('an item template'); //add button after so you can test delete 
      return this; 
     }, 
     unrenderItem: function(){ 
      alert('unrenderitem called in itemview'); 
      $(this.el).remove(); 
     }, 
     removeItem: function(){ 
      alert('removeItem called in itemview'); 
      this.model.destroy(); 
     } 
    }); 

    alert ("before itemview creation"); 
    var itemview = new ItemView(); 
    alert ("now after"); 

    var AllItemView = Backbone.View.extend({ 
     el: $('body'), //el attaches to existing element <-- what does this mean? 
     events: { 
      'click button#addItemButton': 'addItem' 
     }, 
     initialize: function(){ 
      alert('initialize called in allitemview'); 
      _.bindAll(this,'renderAllItem', 'addItem', 'appendItem'); 
      this.collection = new ItemCollection(); 
      this.collection.bind('add', this.appendItem); //Problem here 
      this.counter = 0; 
      this.renderAllItem(); 
     }, 
     renderAllItem: function(){ 
      alert('renderallitem called in allitemview'); 
      var self = this; //why 
      $(this.el).append('<button id="addItemButton"> Add Item </button>'); 
      $(this.el).append('<ul></ul>'); 
      _(this.collection.models).each(function(item){ //in case collection is not empty 
       self.appendItem(item); 
      },this); //what is this function 
     }, 
     addItem: function(){ 
      alert('addItem called in allitemview'); 
      this.counter++; 
      var thisItem = new Item(); 
      thisItem.item({ItemName:thisItem.get('ItemName')+this.counter 
      }); 
      this.collection.add(thisItem); //add is a function defined for the collection 
      this.appendItem(thisItem); 
     }, 
     appendItem: function(item){ 
      alert("append item called in allItemview"); 
      var itemView = new ItemView({ 
       model: Item //DO NOT CAPITALIZE!!!... or do capitalize?... 
      }); 
      $('ul',this.el).append(itemView.renderItem().el); 
     } 
    }); 
})(jQuery); 
+0

爲什麼你將兩個不同的方法綁定到同一個集合回調?你是否試圖在添加單個項目時與完成項目集合添加時做什麼? (這與嵌套模型無關,這是一個完全獨立的問題) – tkone 2012-07-24 21:35:08

+0

請參閱編輯。感謝您的幫助 – Mark 2012-07-24 21:48:24

回答

0

,我認爲你的目標是使某種層次。

首先: 在appendItem函數中不應該爲itemView的模型爲model:item而不是model:Item。我沒有看到任何地方定義的項目。

接下來,你爲什麼不使用?:http://backbonejs.org/#Collection-add

appendItem似乎是多餘的。您似乎也想在收藏更改後添加新視圖。那麼在這種情況下,您可能希望爲您的收藏夾或路由器提供將事件與變化綁定的視圖。這個問題可能有幫助嗎?:Backbone.Collection.Create not triggering "add" in view

希望有幫助!

+0

我將添加我的代碼,以便您可以看到我真的在做什麼/出錯。 1秒。再次,我只是跟着一個教程,所以我沒有很好的理由,我正在做的一切>< – Mark 2012-07-24 22:19:22

+0

你完全正確的,我試圖呈現一個層次結構。問題是我跟隨的教程分別依賴於綁定添加和AppendItem或AppendSet。當您擁有層次結構時,這會導致問題。我想知道如何做到這一點,讓我有一個層次結構。 – Mark 2012-07-24 22:32:27

+0

它是否將項目添加到集合中,還是隻是不渲染它? – Parris 2012-07-24 22:36:59