Browser + Backbone.js "ApplicationState" common module

I don't understand how to split some kind of "single" application state object model, between different views using the browser. Books and tutorials often use the global namespace, for example:

var app = app || {};

      

I have a simple example application consisting of:

app.js

var $ = require('jquery');
var Backbone = require('backbone');
Backbone.$ = $;

var MenuView = require('./views/MenuView');
var ContainerView = require('./views/ContainerView');

new MenuView();
new ContainerView();

      

MenuView.js

var Backbone = require('backbone');
var ApplicationState = require('../models/ApplicationState');

module.exports = Backbone.View.extend({
    el: '#menuView', 
    events: {
        'click .menuLink': 'changePage'
    },
    changePage: function(event) {
        event.preventDefault();
        var viewName = $(event.target).attr('data-view');
        ApplicationState.set('currentView',viewName);
    }
});

      

ContainerView.js

var Backbone = require('backbone');
var ApplicationState = require('../models/ApplicationState');

module.exports = Backbone.View.extend({
    el: '#containerView', 
    initialize: function() {
        this.listenTo( ApplicationState, 'change', this.render );   
        this.render();
    },
    render: function() {
        this.$el.html( ApplicationState.get('currentView') );
    },
    close: function() {
        this.stopListening();
    }
});

      

It seems to work using this approach:

ApplicationState.js   var Backbone = require ('backbone');

var ApplicationState = Backbone.Model.extend({
    defaults: {
        currentView: 'TransactionListView'
    }
});

module.exports = new ApplicationState();

      

Is the ApplicationState module really only created once (caching)? Or is there a risk of re-creating / resetting the module?

What's the best practice for my use case? Thank you very much.

+3


source to share


1 answer


Yes, the example you gave will only have one ApplicationState. Browserify does everything that follows module.exports =

as soon as the js file starts up, and then everything that requires that file is passed a link to the result.

However, it is generally best to avoid sharing this technique between views and instead use a parent view that delegates to subviews. There are several ways to set this up. For guidance on best practices for organizing a basic application, check out this conversation: https://www.youtube.com/watch?v=Lm05e5sJaE8

In this example, I would most likely consider using the Backbone Router . In your example, you have a navigator that changes the "main" view. Backbone.Router intercepts the navigation and checks it against your specified routes by calling your view method. For example:

router.js



module.exports = Backbone.Router.extend({
    initialize: function(options){
        this.ContainerView = new ContainerView();
    },
    routes: {
        'transactions': 'showTransactionListView',
        'transaction/:id': 'showTransactionDetailView'
    },
    showTransactionListView: function() {
        this.ContainerView.render('TransactionListView');
    },
    showTransactionDetailView: function(id) {
        this.ContainerView.render('TransactionDetailView', id);
    }
});

      

Then any link to #transations

(or simply transactions

, if you use History of the bbb>) is called to your ContainerView.render('TransactionListView')

. And, as a bonus, if you reload the page, you'll still be looking at TransactionListView

.

Other Notes:

  • You want to make sure you discard old views when you replace them (by calling .remove()

    on them) to avoid memory leaks. additional literature
  • You can add some flexibility to your router and use the controller template to render subviews with this great plugin
+5


source







All Articles