gpt4 book ai didi

javascript - Marionette CollectionView 在 collection.fetch 后不会重新渲染

转载 作者:行者123 更新时间:2023-11-27 23:23:29 25 4
gpt4 key购买 nike

我有一个“电子邮件”样式的应用程序,它显示按日期分组的消息。当应用程序加载时,会获取浅层消息集合并将其加载到 Backbone 集合中。集合中的每个模型代表一个分组内的消息列表。 MessageGroup 表示一组消息,MessagesView 显示消息组。

这一切都运行良好,直到再次获取集合,就像应用过滤器之后一样,仅显示组标题,而不显示其中的消息。我尝试触发 MessagesView 可以监听的事件,然后重新渲染自身,但出现错误:listening.obj.off 不是函数

var MessageModel = Backbone.Model.extend({});
var MessageCollection = Backbone.Collection.extend({
model: MessageModel
});

var GroupModel = Backbone.Model.extend({});
var GroupCollection = Backbone.Collection.extend({
model: GroupModel,
url: '/messages/recipient',
parse: function (response) {

// Create a grouped JSON to render nested views with
var messageArray = [];
var groupedlist = _.groupBy(response.messages, function(model) {
return model.publishDate;
});

_.forEach(groupedlist, function(n, key) {
var grouping = {};
grouping.group = key;
grouping.list = n;
messageArray.push(grouping);
});

return messageArray;
},
fetchMessages: function() {
this.fetch({
data: filtermodel.toJSON(),
success: function() {

var messagecollection = new MessageCollection();

// Loop through each grouping and set sub-collections
groupcollection.each(function(group) {
var list = group.get('list');

messagecollection.reset(list);
group.set('list', messagecollection);
});
}
});
}
});

// Model to track applied filters
var FilterModel = Backbone.Model.extend({
defaults: {
folder: 0
}
});

// ------------------------ VIEWS ------------- //

// View for a single Message
var MessageView = Backbone.Marionette.ItemView.extend({
template: require('../../../templates/activities/message-item.ejs'),
events: { 'click li.item': 'getMessageDetail' },
getMessageDetail: function(e){
this.triggerMethod('showDetail', this.model);
//initMessageDetail(this.model);
}

});

// Grouped container view for a list of Messages within a group
var MessageGroup = Backbone.Marionette.CompositeView.extend({
template: require('../../../templates/activities/message-list.ejs'),
className: "list-view-group-container",
childView: MessageView,
childViewContainer: "ul.viewcontainer",
initialize: function() {
this.collection = this.model.get('list');

}

});

// Top level view for all grouped messages
var MessagesView = Backbone.Marionette.CollectionView.extend({
childView: MessageGroup,
initialize: function() {
this.collection.on('change', this.log, this);
},
log: function() {
console.log('triggered log');
}
});

// View for selected message detail
var MessageDetailView = Backbone.Marionette.ItemView.extend({
template: require('../../../templates/activities/message-detail.ejs'),
className: "message-content-wrapper"
});

// View for filter selection bar
var MessageFilterView = Backbone.Marionette.ItemView.extend({
template: require('../../../templates/activities/message-filter-bar.ejs'),
events: {
'click #search-btn': function() {
filtermodel.set('search', $('#search-input').val());
groupcollection.fetchMessages();
}
}
});


var filtermodel = new FilterModel();
var groupcollection = new GroupCollection();

// Fetch messages first run
groupcollection.fetchMessages();


// LayoutView to display in center panel of application
module.exports = ViewMessages = Marionette.LayoutView.extend({
template: require('../../../templates/activities/viewmessages.ejs'),
className: 'content full-height',
regions: {
'messagelistregion': '#messageList',
'messagedetailregion': '.message-detail',
'messagefilterregion': '.filter-bar'
},
childEvents: { 'showDetail': 'onMessageSelected' },
onMessageSelected: function (childView, childViewModel) {

var that = this;

var detailModel = childViewModel.clone();
var messageDetailView = new MessageDetailView({model:detailModel});
that.messagedetailregion.show(messageDetailView);
},
onShow: function(){

var that = this;
var messagesview = new MessagesView({
collection: groupcollection
});

var messageFilterView = new MessageFilterView();
that.messagelistregion.show(messagesview);
$("#messageList").ioslist();

that.messagefilterregion.show(messageFilterView);
this.messagedetailregion.on('show', function() {
console.log('message detail region shown:' + that.messagedetailregion.currentView);
})
}
});

我认为这是因为在成功回调中构建消息分组所完成的工作在触发重置事件和刷新 View 之前尚未完成。如何让 MessagesView 在后续提取后更新?

更新:我将集合分组到其分层树/叶结构的成功后逻辑移至顶级 Collection View (MessagesView) 中的自定义事件 (fetchSuccess):

var MessagesView = Backbone.Marionette.CollectionView.extend({
childView: MessageGroup,
initialize: function() {
this.collection.on('fetch:success', this.fetchSuccess, this);
},
fetchSuccess: function() {
var messagecollection = new MessageCollection();

groupcollection.each(function(group) {
var list = group.get('list');

messagecollection.reset(list);
group.set('list', messagecollection);
});
}
});

在获取成功回调中触发。我很确定这是渲染集合的好方法,但我似乎无法解决 Marionette 中的错误:

**Uncaught TypeError: listening.obj.off is not a function**

有人知道为什么这个 Collection View 不会重新渲染吗?

最佳答案

我能够确定集合中模型的创建发生在重置事件之后,但在构建嵌套模型的结构之前:

success: function() {

var messagecollection = new MessageCollection();

// Loop through each grouping and set sub-collections
groupcollection.each(function(group) {
var list = group.get('list');

messagecollection.reset(list);
group.set('list', messagecollection);
});
};

在任何过滤事件、分组、排序等之后,每次都需要将集合结构修改为这个嵌套层次结构。该 View 在构建结构之前拾取重置事件,因此 subview 没有要渲染的数据。我通过在更改后克隆原始集合并让 View 呈现克隆的集合来修复此问题:

groupcollection.fetch({
reset: true,
data: filtermodel.toJSON(),
success: function() {

groupcollection.each(function(group) {
var list = group.get('list');

var messagecollection = new MessageCollection(list);
group.set('list', messagecollection);
});

filteredcollection.reset(groupcollection.toJSON());
}
});

关于javascript - Marionette CollectionView 在 collection.fetch 后不会重新渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35180599/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com