2014-07-01 24 views
0

我正在用Javascript Backbone框架和標準的下劃線模板引擎構建一個網站。我有我加載第一頁加載的列表視圖。由於這個列表的內容可能會改變服務器端,我想每兩秒更新一次這個列表。我試圖通過添加一個setInterval調用來做到這一點:如何輪詢更新Backbone下劃線模板?

var OpenTicketListView = Backbone.View.extend({ 
    el: '#the-id-in-the-template', 
    render: function() { 
     var that = this; 
     var tickets = new TicketColection(); 
     tickets.fetch({ 
      success: function(openTickets){ 
       console.log('WE GOT A RESPONSE!'); 
       var template = _.template($('#my-template').html(), {tickets: tickets.models}); 
       that.$el.html(template); 
      } 
     }); 
    } 
}); 

var openTicketListView = new OpenTicketListView(); 

router.on("route:home", function() { 
    openTicketListView.render(); 
    assignedTicketListView.render(); 
}); 

setInterval(openTicketListView.render, 2000); 

這個設置似乎幾乎工作。 listview首次呈現完美。 setInterval似乎也起作用,因爲它從服務器獲取更新列表,這在控制檯中看起來不錯(具有更新的內容)。我也看到了「我們得到了迴應!」在控制檯。但是,它拒絕做的唯一事情是視覺上更新視圖。

有人知道我在這裏可能會做錯嗎?我在這裏的愚蠢是什麼?我怎樣才能調試呢?

歡迎所有提示!

回答

1

問題是,當您從setInterval調用函數時,render函數內部的this的值將丟失。解決的方法之一,這將是對bind上下文的功能:

setInterval(openTicketListView.render.bind(openTicketListView), 2000); 

其值得一提的,沒有必要調用直接渲染功能。相反,您可以從輪詢方法調用fetch,並將視圖綁定到集合的sync事件,然後重新呈現它自己。這樣的事情:

var OpenTicketListView = Backbone.View.extend({ 
    el: '#the-id-in-the-template', 
    initialize: function() { 
     this.listenTo(this.collection, 'sync', this.render); 
     this.collection.fetch(); 
    }, 
    render: function() { 
     console.log('WE GOT A RESPONSE!'); 
     var template = _.template($('#my-template').html(), {tickets: this.collection.models}); 
     that.$el.html(template); 
    } 
}); 

var tickets = new TicketColection(); 
var openTicketListView = new OpenTicketListView({ collection: tickets }); 

setInterval(tickets.fetch.bind(tickets), 2000); 
+1

我可能會用'this.listenTo(this.collection,...)'而不是'this.collection.bind(...)',這會節省你一個'Function.prototype.bind'調用,幫助避免內存泄漏,並幫助建立良好的事件綁定習慣。 –

+0

@ muistooshort不錯。更新了答案。 – levi