Marionette CollectionView nicht re-Rendern nach der Sammlung.Holen

Ich habe eine ‚E-Mail‘ – Stil-app, die zeigt Nachrichten gruppiert nach Datum. Wenn die app lädt, eine seichte Sammlung von Nachrichten werden abgerufen und geladen in einem backbone-Sammlung. Jedes Modell in der Kollektion stellt eine Liste von Nachrichten, die innerhalb einer Gruppierung. Die MessageGroup repräsentiert eine Gruppe von Nachrichten und die MessagesView zeigt die Gruppen von Nachrichten.

Das alles funktioniert gut, bis die Sammlung geholt wird, wieder wie nach einem filter angewendet wird, werden nur die Gruppenköpfe angezeigt werden, nicht die Nachrichten im inneren. Ich habe versucht, das auslösen eines Ereignisses, dass die MessagesView warten können, dann neu Rendern selbst, sondern bekomme ich eine Fehlermeldung: listening.obj.off is not a function.

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);
        })
    }
});

Ich ‚ m denken sein, weil die Arbeit, die getan wird, bauen sich die Gruppierung der Nachrichten in der Erfolgs-callback nicht beenden, bevor der reset-Ereignis wird ausgelöst, und die Ansicht aktualisiert wird. Wie bekomme ich die MessagesView update nach weiteren holt?

UPDATE:
Ich zog die post-Erfolgs-Logik der Gruppierung der Sammlung in Ihrer hierarchischen Baum/Blatt-Struktur, um ein benutzerdefiniertes Ereignis (fetchSuccess) in der top-level-collectionview (MessagesView):

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);
        });
    }
});

Es ausgelöst werden in der Erfolgs-callback von fetch. Ich bin mir ziemlich sicher, dies ist eine gute Art und Weise der Erbringung der Sammlung, aber ich kann nicht scheinen zu bekommen, um die Fehler in der Marionette:

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

Jemand irgendwelche Ideen, warum dies collectionview wird nicht re-Rendern??

InformationsquelleAutor JToTheC | 2016-02-03



One Reply
  1. 1

    Konnte ich feststellen, dass die Erstellung der Modelle in der Sammlung eingetreten, nachdem die reset-Ereignis, aber bevor die Struktur der geschachtelten Modelle gebaut wurde out:

    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);
        });
    };

    Nach jedem event filter, Gruppierung, Sortierung etc., die Sammlung Struktur muss geändert werden, in diesem verschachtelten Hierarchie jeder Zeit. Die Aussicht war Kommissionierung bis die reset-Ereignis, bevor die Struktur wurde gebaut, so dass die untergeordneten Ansichten hatte keine Daten zu Rendern. Ich reparierte dies durch das Klonen der original-Sammlung nach den änderungen und mit der Aussicht machen die geklonten Sammlung:

    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());
        }
    });

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.