Search code examples
javascriptbackbone.jsmarionette

What is the best way to add model in a collection from view?


I have a Backbone Marionette app with Router and a Controller. In my app you can view a collection of texts (index route with collection fetching from server), can view existing collection of texts (indexPage route without fetching from server) and can create a new text (form route). Views of list texts and create form are different from each other and changes in region.

I want to add a successully saved model to a collection and then redirect to indexPage route, but what is the best way to get a texts collection from _FormView success callback? Or how to restruct an app to do it simple?

I can send event to a controller with Backbone.Radio but want to deal without it.

Routes

router.processAppRoutes(controller, {
    '': 'index',
    'index': 'indexPage',
    'create': 'form'
});

Controller

_Controller = Marionette.Controller.extend({
    initialize: function () {
        this.list = new _MainTexts();
    },
    index: function () {
        if (!_.size(this.list)) {

            var
            self = this;

            this.list.fetch({

                success: function (collection, response, options) {
                    self.indexPage();
                    return;
                }
            });
        }
        this.indexPage();
    },
    indexPage: function () {

        var
        textsView = new _TextsView({
            collection: this.list
        });
        application.getRegion('contentRegion').show(textsView);
    },
    form: function () {

        var
        formView = new _FormView({
            model: new _MainText()
        });
        application.getRegion('contentRegion').show(formView);
    }
});

Views

_TextView = Marionette.ItemView.extend({

    className: 'item text',
    template: function (serialized_model) {
        return _.template('<p><%= texts[0].text %></p>')(serialized_model);
    }
});

_TextsView = Marionette.CollectionView.extend({
    className: 'clearfix',
    childView: _TextView
});

Form view

_FormView = Marionette.ItemView.extend({
    template: '#form-template',
    ui: {
        text: 'textarea[name="text"]',
        submit: 'button[type="submit"]'
    },
    events: {
        'click @ui.submit': 'submitForm'
    },
    submitForm: function (event) {

        event.preventDefault();
        this.model.set({

            text: this.ui.text.val()
        });

        this.model.save({}, {
            success: function (model, response, options) {

                ???
            }
        });
    }
});

Solution

  • Ok, my problem solution is here. In controller action "form" I create event listener

    var
    formView = new _FormView({
    
        model: model
    });
    
    formView.on('formSave', function (model) {
    
        if (id == null) {
    
            self.list.add(model);
        }
    
        ...
    });
    

    Then in form view I trigger event

    this.model.save({}, {
    
        success: function (model, response, options) {
    
            if (response.state.success) {
    
                self.trigger('formSave', model);
            }
        }
    });
    

    That's all:)