页面多次刷新/重新加载

我正在学习JavaScript和backbone.js并尝试开发一个小型Web应用程序。 但问题是我的页面(图形)被重载多次(超过预期)。 因此页面会在页面稳定并显示图形之前自动重新加载(超快)页面。 当我说“重新加载浏览器”时,我的意思是说谷歌浏览器刷新图标的重新加载图标会多次刷新/(正向旋转,向后旋转),最后显示数据。

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

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

HTML:

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

视图模型

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

  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 }); }); 

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

问题:页面刷新了大约5-6次,最后图形完全加载。

FootNote:我的渲染function有问题吗。 请指导。

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

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

删除this.model.on('change', this.render, this); 或者使用model的toJSON()方法获取它的数据副本并将其传递给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处理的一次性活动,并且只应在其中添加一次初始化代码 。 我甚至无法通过在已初始化的模型上手动调用initialize来考虑您尝试实现的目标。

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

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

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

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

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


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