0
votes

I have configured requirejs to load the core libs (jquery, underscore, backbone). Now I would like to add my backbone models, controllers, views, etc to be loaded asyncronly

I found a lots of tutorials to this topic and lots of "ready" boilerplates unfortunatly I mentioned that most approaches are depreceated or rather complicated (even there are better approaches).

One example is how I configured requirejs for the main libs: https://stackoverflow.com/a/10914666/1309847

So how do I load Backbone Views, Models, Collections, Routers, Controllers and Templates with a simple and valid Requirejs configuration?

I followed youre advice but get some strange error

main.js

require.config({
    paths: {
        jquery: 'vendors/jquery/jquery',
        underscore: 'vendors/underscore/underscore',
        backbone: 'vendors/backbone/backbone'
    },
    shim: {
        underscore: {
            exports: '_'
        },
        backbone: {
            deps: ['underscore', 'jquery'],
            exports: 'Backbone'
        }
    }
});

require(['app'], function(app){

});

app.js

define(['jquery', 'underscore', 'backbone'], function($, _, Backbone){
    var Message = new Backbone.Model.extend({
        //idAttribute: '_id',
        //defaults: { body: '' }
        //url: function(){ return this.id ? '/messages/' + this.id : '/messages'; }
    });

    var newMessage = new Message({ body: 'hi' });
    newMessage.save();
});

The error occours in app.js:

Uncaught TypeError: Object [object Object] has no method 'apply' 

When I comment the new Backbone.Model.extend part I don't get any error anymore.

2
Seems a problem loading underscore or backbone. Put a breakpoint in the second line of app.js and check if "_" or "Backbone" are undefined. In that case, check your paths, and the libs version seeking compatibility problems. If everything fails, try using the AMD-versions of Backbone and undercore: github.com/amdjseabait
I did a console.log with all three parameters. All three look valid but I have specified the error some more. It happens when I want to create a new Message instance. (I also can uncomment the schema but instancing it gives the error)dev.pus
Ok, remove the "new" in this line "var Message = new Backbone.Model.extend". It should be var Message = Backbone.Model.extendeabait
This was it :) Thank you for the help I would never managed alonedev.pus
no problem, it was my pleasure to help youeabait

2 Answers

1
votes

in my experience, the best way to bootstrap your application is by creating a Backbone.Router. So you can associate urls with your application functionality. If you are using RequireJS+Backbone, you probably have a main.js where RequireJS is configured (paths, shims, etc). The first call to "require" is used to load a initial script in order to bootstrap the whole app. For example:

/**
* main.js - RequireJS bootstrap
*/
require.config({
  paths: {
    //your paths
  },
  shim: {
    //your shims
  }
});

require(
  [
    'app' //app.js is at the same directory as main.js 
  ],
  function(app) {
    app.init();
  }
);

then in app.js you can create a new Router instance, or you can just start creating Views and Models.

For further reference: http://addyosmani.github.com/backbone-fundamentals/

0
votes

So as I have now understood right: You have to wrap a requirejs function around youre own custom js file.

The function is called define. The first parameter is an array of the dependencies which you have defined in the main.js file or a relative path to another custom js from you. The second parameter is the callback which holds the original file. Important is that you return the object, function, array or variable which you want to share.

The whole thing looks like this:

define(
    ['underscore', 'backbone'], // the dependencies (either relative paths or shortcuts defined in main.js
    function(_, Backbone){ // the return statement of the deps mapped to a var
        var MessageModel = Backbone.Model.extend({ // the original code, file
            defaults: { body: '' },

            initialize: function(){}
        });

        return MessageModel; // the return statement, sharing the "final result", sometimes you return the initialize parameter
    });

The same for a collection wrapping the models:

define(
    ['jquery', 'underscore', 'backbone', 'models/message_model'], // deps and the last one is the relative path
     function($, _, Backbone,MessageModel){ // same as above explained
var MessageCollection = Backbone.Collection.extend({
    model: MessageModel,

    initialize: function(){}
});

return MessageCollection;

});

I now only have to figure out how I can bootstrap to whole application. But I think I need more knowledge of backbone to do this :)