How to dynamically update a Marionette CollectionView when the underlying model changes

心不动则不痛 提交于 2019-12-11 00:54:27

问题


Seems like this should be obvious, but there seem to be so many different examples out there, most of which cause errors for me, making me think they are out of date. The basic situation is that I have a MessageModel linked to a MessageView which extends ItemView, MessageCollection linked to a MessageCollectionView (itemView: MessageView). I have a slightly unusual scenario in that the MessageCollection is populated asynchronously, so when the page first renders, it is empty and a "Loading" icon would be displayed. Maybe I have things structured incorrectly (see here for the history), but right now, I've encapsulated the code that makes the initial request to the server and receives the initial list of messages in the MessageCollection object such that it updates itself. However, I'm not clear, given this, how to trigger displaying the view. Obviously, the model shouldn't tell the view to render, but none of my attempts to instantiate a view and have it listen for modelChange events and call "render" have worked.

I have tried:

  1. No loading element, just display the CollectionView with no elements on load, but then it doesn't refresh after the underlying Collection is refreshed.
  2. Adding modelEvents { 'change': 'render' } to the view --> Uncaught TypeError: Object function () { return parent.apply(this, arguments); } has no method 'on'
  3. I also tried this.bindTo(this.collection..) but "this" did not nave a bindTo method
  4. Finally, I tried, in the view.initialize: _.bindAll(this); this.model.on('change': this.render); --> Uncaught TypeError: Object function () { [native code] } has no method 'on'

Here is the code

    Entities.MessageCollection = Backbone.Collection.extend({
        defaults: {
            questionId: null
        },
        model: Entities.Message,
        initialize: function (models, options) {
            options || (options = {});
            if (options.title) {
                this.title = options.title;
            }
            if (options.id) {
                this.questionId = options.id;
            }
        },
        subscribe: function () {
            var self = this; //needed for proper scope
            QaApp.Lightstreamer.Do('subscribeUpdate', {
                adapterName: 'QaAdapter',
                parameterValue: this.questionId,
                otherStuff: 'otherstuff',
                onUpdate: function (data, options) {
                    console.log("calling sync");
                    var obj = JSON.parse(data.jsonString);
                    self.set(obj.Messages, options);
                    self.trigger('sync', self, obj.Messages, options);
                }
            });
        },
    });

    Views.MessageCollectionView = Backbone.Marionette.CollectionView.extend({
        itemView: Views.MessageView,
        tagName: 'ul',
//        modelEvents: {
//            'change': 'render'
//        },
        onAfterItemAdded: function (itemView) {
            this.$el.append(itemView.el);
        }
    });

var Api = {
        subscribe: function (id) {
            var question = new QaApp.Entities.Question(null, { id: id });
            question.subscribe();
            var questionView = new QaApp.Views.QuestionView(question);
            QaApp.page.show(questionView);
        }
    };

I am very grateful for all the help I've received already and thanks in advance for looking.


回答1:


Try this:

var questionView = new QaApp.Views.QuestionView({
    collection: question
});


来源:https://stackoverflow.com/questions/18650469/how-to-dynamically-update-a-marionette-collectionview-when-the-underlying-model

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!