2012-07-13 47 views
0

我遇到以下問題。在用戶事件(點擊.twitterDefault)我叫保存事件與Backbone,在model.save之後調用view.render時未設置一個字段

twitter : { 
        handle : handle, 
        ignore : false 
} 

然後成功函數被調用,我在模型上(Klout的,Twitter和測試儀)設置字段。所有的字段都設置了(日誌語句全部打印出適當的對象)

然後,我調用view.render(),這裏的twitter沒有設置了,我不知道爲什麼,保存後沒有同步發生Twitter的沒有得到覆蓋(另外我確信的Twitter也被保存在服務器上的成功方法被調用之前)。

任何幫助,不勝感激!

代碼如下(剝離以提高可讀性)

$(function(){

var ContactModel, 
    ContactModelCollection, 
    ContactView, 
    ContactCollectionView, 
    contacts, 
    contactCollectionView; 

//base model 
ContactModel = Backbone.Model.extend({ 
    defaults : { 
    }, 
    initialize : function() { 
    } 
}); 

ContactModelCollection = Backbone.Collection.extend({ 
    model : ContactModel, 
    url : '/api/contacts', 
    comparator : function(contact) { 
     return contact.get('strength_of_relationship'); 
    }, 
    initialize : function() { 
    } 
}); 

ContactView = Backbone.View.extend({ 
    tagName : 'li', //attempting to create a new element 
    render: function() { 
     var compiled_tmpl = _.template($('#contact-template').html()); 
     var html = compiled_tmpl(this.model.toJSON()); 
     console.log('model.get("twitter")=('+JSON.stringify(this.model.get('twitter)'))+')'); 
     console.log('model.get("klout")=('+JSON.stringify(this.model.get('klout'))+')'); 
     console.log('model.get("tester")=('+JSON.stringify(this.model.get('tester'))+')'); 
     this.$el.html(html); 
     console.log('rendered view successfully)'); 
     return this; 
    }, 
    initialize: function() { 
     console.log('contactView initalized'); 
     this.model.bind('change', this.render, this); 
     this.model.bind('destroy', this.remove, this); 
    }, 
    events: { 
     'click .twitterDefault' : 'assignDefaultTwitterHandle', 
    }, 
    assignDefaultTwitterHandle : function(event) { 
     var handle = $(event.currentTarget).data('twitter'); 
     this.assignTwitterHandle(handle); 
    }, 
    assignTwitterHandle : function(handle) { 
     console.log('model assignTwitterHandle. handle='+handle+')'); 
     var view = this, 
      model = view.model; 
     model.save({ 
      twitter : { 
       handle : handle, 
       ignore : false 
      }, 
      id : model.get('id') 
     }, { 
      error : function() { 
       console.log('saving twitter handle failed'); 
      }, 
      success : function(model, response) { 
       console.log('response=('+JSON.stringify(response)+')'); 
       if(response.error) { 
        console.log('error on server ='+response.error); 
       } 
       if(response.twitter) { 
        console.log('twitter is set'); 
        var twitter = { 
         handle : handle, 
         tweet : response.twitter, 
         age : new Date() 
        }; 
        console.log('setting twitter to '+JSON.stringify(twitter)); 
        model.set('twitter', twitter); 
        model.set('tester', 'tester'); 
        console.log('twitter after setting it = '+JSON.stringify(model.get('twitter'))); 
        console.log('view\'s model twitter after setting it = '+JSON.stringify(view.model.get('twitter'))); 
       } 

       if(response.klout) { 
        console.log('klout is set'); 
        var klout = { 
         topics : response.klout 
        } 
        console.log('setting klout to '+JSON.stringify(klout)); 
        model.set('klout', klout); 
       } 
       if(response.twitter || response.klout) { 
        console.log('Rerendering view after setting klout/twitter'); 
        view.render(); 
       } 
      } 
     }); 
    } 
}); 

contacts = new ContactModelCollection; 

ContactCollectionView = Backbone.View.extend({ 
    el : $('#suggestions-list'), 
    initialize : function(){ 
     contacts.bind('add', this.addOne, this); 
     contacts.bind('reset', this.addAll, this); 
     contacts.bind('all', this.render, this); 
    }, 
    render : function(){ 
     console.log('contactcollectionview render'); 
    }, 
    addOne : function(contact) { 
     console.log('addOne'); 
     var view = new ContactView({model: contact}); 
     var el = view.render().el; 
     console.log('el=('+el+')'); 
     $('#suggestions-list').append(el); 
    }, 
    addAll : function() { 
     console.log('addAll'); 
     contacts.each(this.addOne); 
    } 
}); 

contactCollectionView = new ContactCollectionView; 


App.contacts = contacts; 
App.contactCollectionView = contactCollectionView; }); 

回答

0

我想這個問題是render功能的範圍。 根據所在的位置,this取值不同。

要始終this指向查看保修範圍,添加到您的initialize

_.bindAll(this,"render"); 

而且,這不是好習慣手動調用view.render。你應該讓事件發揮作用。 Model save已經觸發了一些事件。只要聽他們更新您的視圖。

+0

感謝您的回答corbacho。我不認爲問題在於範圍。首先,如預期的那樣輸出值'klout'和'tester'。此外,更改也綁定到呈現方法,「twitter」仍未定義。我嘗試了註釋手動渲染(在成功回調中),它沒有改變任何東西(除了一個渲染調用較少)。 – forste 2012-07-16 09:49:20

相關問題