页面多次刷新/重新加载
我正在学习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
因为它是一个构造函数。