我创建了一个传递集合视图和集合的集合。该集合引用了我创建的模型。在获取集合时,项目会成功呈现,但是当模型更改时,itemViews不会按预期重新呈现。
例如,tweetCollectionView中的itemAdded函数被调用两次(在fetch上添加了两个模型)但是即使parse函数随着时间的推移为这些模型返回不同的属性(我假设这会调用集合上的change事件) ,或者特别是模型上的更改事件,我试图在ItemView中捕获)itemChanged永远不会被调用,并且itemViews永远不会被重新渲染,我希望在捕获itemViews模型更改事件时完成。
代码如下:
function TweetModule(){
String.prototype.parseHashtag = function() {
return this.replace(/[#]+[A-Za-z0-9-_]+/g, function(t) {
var tag = t;
return "<span class='hashtag-highlight'>"+tag+"</span>";
});
};
String.prototype.removeLinks = function() {
var urlexp = new RegExp( '(http|ftp|https)://[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?' );
return this.replace( urlexp, function(u) {
var url = u;
return "";
});
};
var TweetModel = Backbone.Model.extend({
idAttribute: 'id',
parse: function( model ){
var tweet = {},
info = model.data;
tweet.id = info.status.id;
tweet.text = info.status.text.parseHashtag().removeLinks();
tweet.name = info.name;
tweet.image = info.image_url;
tweet.update_time_full = info.status.created_at;
tweet.update_time = moment( tweet.update_time_full ).fromNow();
return tweet;
}
});
var TweetCollection = Backbone.Collection.extend({
model: TweetModel,
url: function () {
return '/tweets/game/1'
}
});
var TweetView = Backbone.Marionette.ItemView.extend({
template: _.template( require('./templates/tweet-view.html') ),
modelEvents:{
"change":"tweetChanged"
},
tweetChanged: function(){
this.render();
}
})
var TweetCollectionView = Marionette.CompositeView.extend({
template: _.template(require('./templates/module-twitter-feed-view.html')),
itemView: TweetView,
itemViewContainer: '#tweet-feed',
collection: new TweetCollection([], {}),
collectionEvents: {
"add": "itemAdded",
"change": "itemChanged"
},
itemAdded: function(){
console.log('Item Added');
},
itemChanged: function(){
console.log("Changed Item!");
}
});
this.startInterval = function(){
this.fetchCollection();
this.interval = setInterval( this.fetchCollection, 5000 );
}.bind(this);
this.fetchCollection = function(){
this.view.collection.fetch();
this.view.render();
}.bind(this);
//build module here
this.view = new TweetCollectionView();
this.startInterval();
};
我可能会对Marionette处理事件冒泡做出假设,但根据文档,我没有看到任何指向此事的内容。
答案 0 :(得分:0)
在CollectionView
内,执行
this.collection.trigger ('reset')
添加模型后。
这将触发onRender ()
中的ItemView
方法重新渲染。
答案 1 :(得分:0)
我知道我回答了一个老问题,但由于它有很多观点,我以为我会正确回答。另一个答案并没有解决代码的问题及其解决方案(触发重置)将强制所有孩子重新渲染,这既不是必需的也不是理想的。
OP代码的问题是change
不是集合事件,这就是永远不会调用itemChanged
方法的原因。要监听的正确事件是update
,根据Backbone.js catalog of events是
...在添加任意数量的模型后触发单个事件 或从集合中删除。
问题并未说明正在使用的Marionette的版本,但至少会回到2.0.0版CollectionView
将智能地重新呈现集合add
,remove
和reset
事件。来自CollectionView: Automatic Rendering
当视图集合为&#34; reset&#34;时,视图将调用render 自己并重新渲染整个系列。
将模型添加到集合时,集合视图将会 将一个模型渲染到子视图集合中。
从集合中删除模型(或销毁/删除)时, 集合视图将销毁并删除该模型的子视图