Search code examples
javascriptbackbone.jsrequirejsjs-amd

How to load bootstrapped models in Backbone.js while using AMD (require.js)


Backbone.js documentation suggest loading bootstrapped models this way:

<script>
var Accounts = new Backbone.Collection;
Accounts.reset(<%= @accounts.to_json %>);
var Projects = new Backbone.Collection;
Projects.reset(<%= @projects.to_json(:collaborators => true) %>);
</script>

But this is a pattern that can't be used in AMD approach (using require.js)

The only possible solution is to declare global variable storing JSON data and use this variable later in relevant initialize methods.

Is there a better way to do this (without globals)?


Solution

  • This is how we bootstrap data in a way that it doesn't pollute the global namespace. Instead it uses require.js exclusively. It also helps you provide the initial app configuration based on variables within the template.

    Within your rendered page

    <script src="require.js"></script>
    <script>
    define('config', function() {
      return {
        bootstrappedAccounts: <%= @accounts.to_json %>,
        bootstrappedProjects: <%= @projects.to_json(:collaborators => true) %>
      };
    });
    </script>
    <script src="app.js"></script>
    

    globals.js

    This file checks for config and extends itself using any of the data returned

    define([
      'config',
      'underscore'
    ], function(config) {
    
      var globals = {
      };
      _.extend(globals, config);
      return globals;
    
    });
    

    config.js

    This file is needed if you want be able to load the app regardless of if you have defined config in the page.

    define(function() {
      // empty array for cases where `config` is not defined in-page
      return {};
    });
    

    app.js

    require([
      'globals',
      'underscore',
      'backbone'
    ], function(globals) {
    
      if (globals.bootstrappedAccounts) {
        var accounts = new Backbone.Collection(globals.bootstrappedAccounts);
      }
      if (globals.bootstrappedProjects) {
        var projects = new Backbone.Collection(globals.bootstrappedProjects);
      }
    
    });