页面获得 refreshed/reloaded 次

Page getting refreshed/reloaded many times

我正在学习 JavaScript 和 backbone.js 并尝试开发一个小型网络应用程序。 但问题是我的页面(图表)被重新加载了很多次(超出预期)。因此,在页面稳定并显示图形之前,页面会自动重新加载多次(超快)。当我说 "Reload of browser" 我的意思是说 google chrome 刷新图标的重新加载图标刷新/(向前旋转,向后旋转)多次,最后显示数据。

以下是我到目前为止所尝试的简短版本。由于我处于学习阶段,我可能没有制定正确的编码标准。请耐心等待。

所以,我必须在首页显示一张图(稍后我需要在同一页上添加更多图)。该图的数据来自 REST 服务。

HTML:

我有一个锚点和一个模板来显示图表数据。

 <div id ="chartAnchor1"></div>
<script id="myChart-template" type="text/template">
    <canvas id="lineChart"></canvas>
    </script>

视图模型

这是针对图形特定数据的:

  var firstSubViewModel = Backbone.View.extend({
    template: _.template($('#myChart-template').html()),
    events: {
  'click .Refresh': 'fetchModelData'
    },
      fetchModelData: function() {
      this.model.initialize();
    },
    render: function() 
    {
      $(this.el).html(this.template());
      var ctx = $(this.el).find('#lineChart')[0];
      var lineChart = new Chart(ctx, {
        type: 'line',
        data: {
          labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
          datasets: [{
            data: this.model.attributes.incThisYear
          }, {
            data: this.model.attributes.incLastYear
          }]
        },
                labelString: 'Income in $'
              }
            }]
          }
        }
      });
    },
   initialize: function() {
      _.bindAll(this, "fetchModelData");
      this.model.on('change', this.render, this);
    }
  });

  return firstSubViewModel;
});

控制器:

  var ch = new dashboardModel.chart({});
  if (// some condition) {
    var data = { // some data};
    ch.fetch(data)
  }     
  //Main Graph on Dashboard
  new firstSubViewModel({
    el: '#chartAnchor1',
    model: ch
  });

});

型号: 我有一个模型 class 从 REST 服务获取数据。

问题:页面刷新了 5-6 次,最终图表完美加载。

脚注:我的渲染函数有什么问题吗?请指导。

您已使用 this.model.on('change', this.render, this); 将模型的更改事件绑定到视图的渲染方法,这意味着对于模型的每次更改,视图都将重新渲染。

并且您将模型属性直接传递给某些 Chart() 函数。我们不知道它里面发生了什么,但很可能它在绘制图表时多次更新模型属性,显然每次更改都会导致另一个 render 再次调用 Chart() 方法,从而调用render 并因此创建一个渲染循环,其长度可能与 Chart() 函数对模型所做的更改次数一样长。

要么删除 this.model.on('change', this.render, this); 要么使用模型的 toJSON() 方法来获取其数据的 copy 并将其传递给 chart() 方法进行绘图.像这样的用例是 toJSON() 方法存在的原因。


另一个问题是处理异步 fetch,我认为 this.model.on('change', this.render, this); 是您试图处理这个问题,但这是错误的。要么你应该听 sync 之类的事件,比如

this.model.on('sync', this.render, this);

或者做类似的事情:

var ch = new dashboardModel.chart({});
/* ---------------------------^ this is the actual model constructor?
 Then what's dashboardModel?! Bad naming ;) */

ch.fetch({
  success: function(model, response) {
    new firstSubViewModel({
      el: '#chartAnchor1',
      model: ch
    });
  }
});

除此之外,您不应手动初始化模型。它是由Backbone.js处理的一次性activity,只需要在其中添加一次性初始化代码。我什至想不出你试图通过在已经 初始化的 模型上手动调用 initialize 来实现什么。

要从持久层获取数据,您应该使用 fetch() 方法。

fetchModelData: function() {
  this.model.fetch({/* options */});
}

您在控制器中的代码有很多问题。它似乎尝试 fetch() 一个带有一些 数据 ? 的模型,但是 fetch 方法只接受 选项 ,主要是为了像我上面使用的那样自定义和处理 AJAX 调用(也许它们实际上是选项,但你将其命名为 data?!在那种情况下忽略这个)。

还有一个没有引用清理的视图,通过 el 选项直接引用 DOM 如果您创建 firstSubViewModel 的另一个实例,这将导致问题,使用on 而不是 listenTo 等都会导致经典的 Backbone.js 错误,如内存泄漏、事件问题等。

所有这些都无法在答案中处理,因此我建议正确阅读文档并对常见的 Backbone.js 问题进行一些研究。


旁注:根据常见的命名转换,firstSubViewModel 应该是 FirstSubViewModel 因为它是一个构造函数。