我有一个使用Marionette构建的单页应用程序,其主视图包含子视图列表。
保存所有应用程序数据的JSON不断更新。我试图将区域显示代码分开,以便它只运行一次而不是每次渲染。
现在,即使JSON是静态数据,也会在每个超时循环上触发render事件,因此change事件不应该调用render。怎么了?我假设它与.set有关但是有没有其他方法可以将数组变量的响应加载到子视图集合,因为fetch只允许url属性并且不接受数组变量?
此示例是应用程序代码的极简化版本,专注于此特定问题。
控制器:
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模型:
MainElement = Backbone.Model.extend({
parse : function(response){
// parsing code
return response;
}
});
MainElementView(布局):
MainElementView = Backbone.Marionette.Layout.extend({
template: "#main-template",
initialize:function(){
//create collection for subelements
this.subElementCollection = new SubElementCollection();
//listen to change event, and fire callback only when change in model is detected
this.model.on('change', this.render, this);
},
regions:{
subsection : ".subsection"
},
onShow: function(){
// show subelements in subsection region when mainelementview is shown on screen, but not show on every render
this.subsection.show(new SubElementCompositeView({collection:this.subElementCollection}))
},
onRender : function(){
var response = this.model.response;
// get subelements when change event fires and parse the response
this.subElementCollection.set(response,{parse:true});
}
});
SubElement Model,Collection,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
}
});
答案 0 :(得分:0)
Check out the documentation。它说:
A "change" event will be triggered if the server's state differs from the current attributes.
在绑定到模型更改事件MainElementView
的{{1}}中,您实际上是在每次模型更改时都说,请调用渲染。
如果由于更改量的原因,重新绘制整个视图的速度太慢。为什么不让渲染更精细?例如,您可以侦听特定的更改事件,只需更改需要更改的DOM元素:
this.model.on('change', this.render, this);
设置它是更多的工作,但是你可以通过将模型属性名称与DOM元素名称或其他东西相匹配来使它更聪明。