[英]Backbone List View / Rendering List View Items
我對Backbone.js很陌生。 請參閱我的代碼以獲取此處引用的內容。 我有一個視圖,該視圖應該顯示“股票”模型的集合。 該視圖稱為“ StockDashboardView”。 此視圖所需的每種股票模型都可以與“ StockDashboardItemView”一起顯示。 但是,在每個StockDashboardItemView呈現之前,需要分別的股票模型獲取一些數據(請求股票價格),以便StockDashboardItemView可以使用該數據繪制圖形。 StockDashboardView遍歷每個股票模型,並為每個模型創建一個StockDashboardItemView。 我應該得到5個不同的圖形,每個圖形中都有不同的公司數據點。 但是所有圖形都是相同的,這意味着5個StockDashboardItemViews中的每一個都具有相同的模型。 我知道我的提取/循環邏輯是錯誤的,但我不知道如何或為什么。 我還嘗試在單個StockDashboardItemViews中而不是在StockDashboardView中進行獲取(請參閱注釋掉的代碼)。 在console.log語句中查看以下打印語句:(該集合有5個模型)。 有人可以幫我糾正我的邏輯嗎? 謝謝
---------- 1 --------
---------- 1 --------
---------- 1 --------
---------- 1 --------
---------- 1 --------
---------- 2 --------
---------- 3 --------
---------- 2 --------
---------- 3 --------
---------- 2 --------
---------- 3 --------
---------- 2 --------
---------- 3 --------
---------- 2 --------
---------- 3 --------
window.StockDashboardView = Backbone.View.extend({
initialize: function () {
this.render();
},
render: function () {
var stocks = this.model.models;
var len = stocks.length;
var startPos = (this.options.page - 1) * 8;
var endPos = Math.min(startPos + 8, len);
$(this.el).html('<ul class="thumbnails"></ul>');
for (var i = startPos; i < endPos; i++) {
console.log("----------1--------");
var stock = stocks[i];
stock.set("_id", stocks[i].toJSON()["tickerSymbol"]);
stock.fetch({success: function(model, response, options){
stock.set("data", response);
// set interactivity to false
console.log("-----------2---------");
$('.thumbnails', this.el).append(new StockDashboardItemView({model: stock}).render().el);
}});
}
$(this.el).append(new Paginator({model: this.model, page: this.options.page}).render().el);
return this;
}
});
window.StockDashboardItemView = Backbone.View.extend({
tagName: "li",
initialize: function () {
this.model.bind("change", this.render, this);
this.model.bind("destroy", this.close, this);
},
render: function () {
$(this.el).html(this.template(this.model.toJSON()));
var context = this.$("#chart_div")[0];
var stock = this.model;
stock.set("_id", stock.toJSON()["tickerSymbol"]);
//stock.fetch({success: function(model, response, options){
//stock.set("data", response);
// set interactivity to false
console.log("-----------3---------");
var chart = new TFChart(stock.get("_id"), stock.attributes['data'], context, false, this.$("#chart_div").width(), this.$("#chart_div").height());
return this;
//}});
}
});
在for-loop
,您使用stock = stocks[i]
來獲取每張股票,然后取回它們。
但是,由於.fetch
是async
方法,當它開始執行以呈現庫存視圖時,您會注意到庫存現在指向庫存中的最后一項,因此它多次渲染最后一項。
為什么會這樣? 因為var
使用函數作用域,而不是塊作用域(在ES6中,有一個let
可以使用塊作用域,但是這里有點偏離主題了),因此,當他們想要使用stock
,所有.fetch
的成功回調,他們都看到相同的stock
,這將是for循環中最后分配的值,並且應該是庫存的最后一項。
這是一個范圍問題,解決方案是將上下文包裝到一個函數中,因此該函數的范圍將為您保留該項目:
render: function () {
var stocks = this.model.models;
var len = stocks.length;
var startPos = (this.options.page - 1) * 8;
var endPos = Math.min(startPos + 8, len);
// Move this.el to here, so the this.el's this won't be a problem.
var thisEl = this.el;
var fetchStock = function(stock) {
stock.set("_id", stocks[i].toJSON()["tickerSymbol"]);
stock.fetch({success: function(model, response, options){
stock.set("data", response);
// set interactivity to false
console.log("-----------2---------");
$('.thumbnails', thisEl).append(new StockDashboardItemView({model: stock}).render().el);
}});
};
$(this.el).html('<ul class="thumbnails"></ul>');
for (var i = startPos; i < endPos; i++) {
console.log("----------1--------");
fetchStock(stocks[i]);
}
$(this.el).append(new Paginator({model: this.model, page: this.options.page}).render().el);
return this;
}
如您所見,現在當我們調用fetchStock
,它的stock
將引用當前的stocks[i]
,並且不會受到其后的循環的影響。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.