Backbone.js 如何在使用不断更新的JSON时正确更新木偶上的子视图
我有一个用木偶制作的单页应用程序,它有一个带有子视图列表的主视图 保存所有应用程序数据的JSON会不断更新。我已经尝试分离区域显示代码,这样它将只运行一次,而不是每次渲染 现在,即使JSON是静态数据,每个超时循环都会触发render事件,因此change事件不应调用render。怎么了?我假设它与.set有关,但是有没有其他方法将响应从数组变量加载到子视图集合,因为fetch只允许url属性,不接受数组变量 此示例是一个极其简化的应用程序代码版本,用于关注此特定问题 控制器:Backbone.js 如何在使用不断更新的JSON时正确更新木偶上的子视图,backbone.js,marionette,Backbone.js,Marionette,我有一个用木偶制作的单页应用程序,它有一个带有子视图列表的主视图 保存所有应用程序数据的JSON会不断更新。我已经尝试分离区域显示代码,这样它将只运行一次,而不是每次渲染 现在,即使JSON是静态数据,每个超时循环都会触发render事件,因此change事件不应调用render。怎么了?我假设它与.set有关,但是有没有其他方法将响应从数组变量加载到子视图集合,因为fetch只允许url属性,不接受数组变量 此示例是一个极其简化的应用程序代码版本,用于关注此特定问题 控制器: var Cont
var Controller = {
showMainView: function(id){
// create model and fetch data on startup
var mainElement = new mainElement();
var mainElementFetched = mainElement.fetch({url: 'http://json.json'});
// fetch done, create view, show view in region, setTimeout
mainElementFetched.done(function(data){
var mainElementView = mainElementView({model:mainElement});
App.mainRegion.show(mainElementView);
setTimeout(updateJSON, 5000);
}
// timeOut loop to check for JSON changes
var updateJSON = function(){
mainElement.fetch({url: 'http://json.json'});
App.timeOut = setTimeout(updateJSON, 5000);
}
}
}
主要元素模型:
MainElement = Backbone.Model.extend({
parse : function(response){
// parsing code
return response;
}
});
MainElement视图(布局):
子元素模型、集合、ItemView、CompositeView:
SubElement = Backbone.Model.extend({});
SubElementCollection = Backbone.Collection.extend({
model:SubElement,
comparator : function(model){
var price = model.get('price');
return -(price);
},
parse:function(response){
// parsing code to get data to models from differents parts of JSON
return response;
}
});
SubElementItemView = Backbone.Marionette.ItemView.extend({
template: "#subelement-template",
tagName: "tr"
});
SubElementCompositeView = Backbone.Marionette.CompositeView.extend({
template: "#subelements-template",
tagName : "table",
itemView:SubElementItemView,
itemViewContainer : "tbody",
initialize: function(){
this.collection.on('change', this.render, this);
},
appendHtml : function(collectionView,itemView,index){
// SORTING CODE
},
onRender:function(collectionView,itemView,index){
// ADD IRRELEVANT EXTERNAL STUFF TO TEMPLATE AFTER RENDER
}
});
。它说:
在绑定到模型更改事件的main元素视图中:this.model.on('change',this.render,this)代码>,实际上是说每次模型更改时,调用render
如果重新绘制整个视图的速度太慢,这是由于更改量太大所致。为什么不使渲染更细粒度?例如,您可以侦听特定的更改事件,只需更改需要更改的DOM元素:
this.model.on('change:Name', function () {
this.$('[name=Name]').html(this.model.get('Name'));
}, this);
设置这一点需要更多的工作,但您可以通过将模型属性名称与DOM元素名称或其他内容相匹配来让它变得更聪明。因此,在我接受您的答案之前,请澄清一下:即使JSON数据没有更改,每次获取都会触发更改事件?视图正在重新绘制,但我认为,如果JSON提要没有更改,在每次获取时呈现它将是一种糟糕的做法。啊,我明白了,所以您的JSON响应实际上没有什么不同,但它仍在触发更改事件?这不应该发生,您可以从引号中看到,如果服务器的响应有任何不同,它应该只调用set
。JSON对象是否包含任何嵌套对象?可能是主干在两个嵌套对象之间进行相等比较,结果返回false,因此主干在该属性上调用set
。另外,我认为最好在onRender
方法中绑定到模型的更改事件,因为渲染可以在它进入DOM之前调用。谢谢你的想法。我正在构建一个应用程序,JSON将随着时间的推移而改变,但如果每5秒轮询一次,大约95%的时间不会改变。在本例中,JSON是一个静态的JSON,用于找出它为什么不断触发更改事件,也许我可以说得更清楚。JSON被大量嵌套到15个级别。我将尝试手动检查javascript是否认为两次获取调用之间的JSON数据相等。我设法使它能够比较字符串化的JSON数据,并在它们不相等时通过自定义事件触发render。我猜这可能意味着fetch触发的主干更改事件并不总是按照它的意思。
A "change" event will be triggered if the server's state differs from the current attributes.
this.model.on('change:Name', function () {
this.$('[name=Name]').html(this.model.get('Name'));
}, this);