Reputation: 19688
I have three main files:
A) application.js // This resides in rails land at app/assets/javascripts/application.js
B) SOF.js // This resides in rails land at app/assets/javascripts/SOF.js
C) router.js // This resides in backbone land at app/assets/javascripts/backbone/routers/router.js
I am wondering why the declared dependencies in the router.js
are occuring without being called in the router itself. Said another way, the order of events are :
require.js
define()
B.initialize()
C.initialize()
My understanding is that the App.js(A) should init the SOF.js(B), which inits the router in router.js(C), and THEN the router should recognize the route, and follow the appropriate route, and create any models/collections/views there.
Why is it that by just including the files in the define()
portion of require.js method declaration that it causes them to load, EVEN before the files themselves init? If I remove the declaration, they won't load, but then of course, I can't reference them to manually initi them in the appropriate route....
Files for your eyes (with above order of events on left):
Application.js:
1- console.log('Application.js: Started');
require([ 'SOF' ],
function(SOF){
5- console.log("Application.js: initializing SOF...");
SOF.initialize(App.songs); //App.songs is an object that contains the data from the Rails DB
10- console.log("Application.js: SOF_Application Fully initialized");
});
SOF.js:
2- console.log('SOF.js: Started');
define([
'jquery',
'underscore',
'backbone',
'backbone/routers/router',
'd3',
'jquery-ui'
], function($, _, Backbone, Router, d3, $){
var initialize = function(options){
6- console.log('SOF.js: In Initialize, initializing Router:');
6- console.log('SOF.js: options : ', options);
Router.initialize(options);
9- console.log('SOF.js: Finished initializing');
}
return {
initialize: initialize
};
});
router.js:
3- console.log('Backbone Router started');
define([
'jquery',
'underscore',
'backbone',
4- 'backbone/relevantModels....', // Will init just by being here
4- 'backbone/relevantCollections....', // If I remove it from here, and of course its matching name in the following function formal parameter, it will not init/render
4- 'backbone/relevantViews....'
], function($, _, Backbone, RelevantModels, RelevantCollections, RelevantViews){
var BBRouter = Backbone.Router.extend({
routes: {
'new' : 'newSong',
'.*' : 'newSong'
},
newSong: function(){
7b console.log('BB routes => new : newSong');
// THESE ARE ALL COMMENTED OUT (VERIFIED no caching problems) but still init/render because they are declared above
// And if I remove the declaration above, I can't call new RelevantView() since it won't know what RelevantView is
// top side
// RelevantView.render();
// middle
// RelevantView.render();
// bottom
// RelevantView.render();
7b console.log('BB routes: newSong Finished');
}
});
var initialize = function(options){
7a console.log("BB Router => Initializing...");
var bb_router = new BBRouter;
window.router = bb_router; // attach it to the window for debugging
8- console.log('BB Router => Initialized');
Backbone.history.start({root: '/songs/#new'});
};
return {
initialize: initialize
};
});
Also note, on the Rails main Application.html.erb, this is the order of declaration in the <head>
:
<%= stylesheet_link_tag "application", :media => "all" %>
<%= requirejs_include_tag "application" %>
<%= javascript_include_tag "assets" %>
Gemfile:
gem 'rails-backbone', git: 'https://github.com/codebrew/backbone-rails.git', tag: 'v1.1.2'
gem 'requirejs-rails', git: 'git://github.com/jwhitley/requirejs-rails.git'
and Gemfile.lock
GIT
remote: https://github.com/codebrew/backbone-rails.git
revision: 4c1dfba7b4f2a989bd0dbc95d5afd3fc762a0b6d
tag: v1.1.2
specs:
rails-backbone (1.1.2)
coffee-script
ejs
jquery-rails
railties
GIT
remote: git://github.com/jwhitley/requirejs-rails.git
revision: f2330104aeca4d193fd5680a22ae7eee85d814b5
specs:
requirejs-rails (0.9.1)
railties (>= 3.1.1, < 4.1)
Upvotes: 4
Views: 134
Reputation: 5622
Your understanding of the module initialization order is correct, but look at the end of the view module files (e.g., StageView
below):
define([
...
], function(...) {
var StageView = Backbone.View.extend({
...
});
// A singleton
return new StageView();
});
In addition to merely defining a view class, it also directly creates an instance of it. This explains why the view's initialize()
is called when the module is imported (Backbone calls initialize()
from the constructor). It's also the initialize()
method which calls render()
(see, for instance, stageView.js, line 45).
I hope this solves the mystery. :-)
Upvotes: 1