I have the save function of my single page application now up and running, with different front end models and collections in Backbone (a song.js and songsCollection.js), saving to the appropriate backend model in Rails (song.rb). After the user creates a song, comprised of beats and measures, etc....., the backbone routes takes the user to the url containing the song, however, the golbal variable that I used to pass in the all of the songs in the begining of the page start is not getting updated.
How can I call from backbone (either in the routes, or the view), a method or something, to refetch all of the songs from the database, including the recently created song, preferably without changing the Rails side of the URL (prior to the #hash)?
The App.songs variable located within the Assets.js.erb is what I am interested in updated from Rails, after a new song is created.....
I am not opposed to using the gon gem, but if I did, how would I call it to be updated?
Thinking aloud:
Maybe in the assests.js.erb I could have this :
App.updateThis = function(appSongs) {
// then an ajax/pjax call to the Rails songs_controller.rb that returns newAllSongs
appSongs = { songs: newAllSongs }
return appSongs; // this would/should update the global variable
}
Files for reference:
application.js:
require([
'MYAPPLICATION' // this gets passed in as 'Application'
], function(Application){
Application.initialize(App.songs);
});
MYAPPLICATION.js:
define([
'jquery',
'underscore',
'backbone',
'backbone/routers/router', // Request router.js
], function($, _, Backbone, Router){
var initialize = function(options){
window.router = Router.initialize(options);
}
return {
initialize: initialize
};
});
This file is used to package the AssetsPipeline paths to the images and sounds, and pass them to the application when it is rendered, form the gist : https://gist.github.com/patrickberkeley/3879730
assets.js.erb :
App = {};
App.assets = {
// Returns an object containing all of asset pipeline's image paths.
// This hash is because Rails' Asset Pipeline bundles the routes to files
// per user session, then hands that to the user's session browser, for security.
// So we create in Ruby (erb = embedded ruby) a hash of the images to be accessed
// in the JS.
images: {
<% AssetsUtil.images.each do |img| %>
"<%= img %>" : "<%= asset_path(img) %>",
<% end %>
},
// Return a formatted URL for an asset.
path: function(name) {
// If the file is in our images object, pull the path from there.
if (this.images && this.images[name]) {
return this.images[name];
}
// Otherwise, create a generic asset path.
return '/assets/' + name;
}
};
App.songs = {
songs: <%= Song.all.to_json.html_safe %>
};
routes.js (backbone's route, not rails' route)
define([
.... require.js paths .....
], function($, _, Backbone, mainHomeView, beatSliderView, beatBarsView, componentsView, tempoSliderView, transportView, repButtonView, log, songsCollection, songsViewNew, songsViewIndex, songsViewShow, songsViewEdit){
var AppRouter = Backbone.Router.extend({
songs: {},
routes: {
'new' : 'newSong',
'index' : 'index',
':id/edit' : 'edit',
':id' : 'show',
'.*' : 'newSong'
},
newSong: function(){
var view = new songsViewNew({collection : this.songs});
/// A WHOLE BUNCH OF RENDERING....
},
index: function(){
console.log('bb routes index');
},
show: function(id){
var createdSong = this.songs.get(id);
var view = new songsViewShow(createdSong);
},
edit: function(id){
console.log('bb routes edit');
},
});
// Initialize the Router, with the options, where (options) is declared in MYAPPLCIATION.js
// and called from application.js
//
// (options) == 'assest.js.erb' => App.songs{ songs : <%= Song.all.to_json.html_safe %> }
// (options) == All the songs in the DB
var initialize = function(options){
var app_router = new AppRouter;
app_router.songs = new songsCollection();
app_router.songs.reset(options.songs);
name = '';
$('.component').each( function() {
name = name + $(this).attr('id') + '.';
$(this).children('.measure').each( function() {
name = name + $(this).attr('id') + '.';
$(this).children('.beat').each( function() {
name = name + $(this).attr('id') + '.';
});
});
log.sendLog([[1, "Component structure: "+name]]);
name = '';
});
Backbone.history.start();
return app_router;
};
return {
initialize: initialize
};
});
Using:
- rails 3.2.2
- backbone.js via gem 'rails-backbone'
- require.js via gem 'requirejs-rails'