【问题标题】:Backbone List View / Rendering List View Items主干列表视图/渲染列表视图项目
【发布时间】:2015-07-13 07:51:51
【问题描述】:

我对 Backbone.js 很陌生。请参阅我的代码以了解我在此处引用的内容。我有一个视图应该显示“库存”模型的集合。此视图称为“StockDashboardView”。此视图需要的每个库存模型都可以与“StockDashboardItemView”一起显示。但是,在每个 StockDashboardItemView 呈现之前,它各自的 Stock Model 需要获取一些数据(请求股票价格),以便 StockDashboardItemView 可以使用这些数据来绘制图表。 StockDashboardView 循环遍历每个 Stock 模型并为每个模型创建一个 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;
                    //}});     
                }
            });

【问题讨论】:

    标签: javascript backbone.js asynchronous


    【解决方案1】:

    在您的for-loop 中,您使用stock = stocks[i] 获取每个库存,然后获取它们。

    但是,由于 .fetchasync 方法,当它开始执行以呈现股票视图时,您会注意到股票现在指向股票中的最后一项,所以它只是呈现最后一项。

    为什么会这样?因为var使用的是函数作用域,而不是块作用域(在ES6中,有一个let可以使用块作用域,但是这里有点跑题了),所以所有.fetch的成功回调,当他们想用stock,他们看到的都是同一个stock,这将是for循环中最后一个赋值,应该是stocks的最后一项。

    这是一个作用域问题,解决方法是将上下文包装到一个函数中,这样函数的作用域就会为你保留项目:

    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],并且不会受到它后面的循环的影响。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-13
      • 2019-01-11
      相关资源
      最近更新 更多