I am new to both Backbone and Require JS.
I am receiving the following error:
Cannot read property View of undefined.
So Backbone is not available, but I cannot see where the problem is. Any help would be much appreciated.
I have the following 3 files:
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<script data-main="boot" src="../libs/require/require.js"></script>
</head>
<body>
<div id="main">Magic!</div>
</body>
</html>
boot.js:
require.config({
baseUrl: "../",
paths: {
jquery : "libs/jquery/jquery-1.8.3.min",
underscore : "libs/underscore/underscore-min",
backbone : "libs/backbone/backbone-min"
}
});
require( [ "app/views/app" ], function(AppView) {
var app = new AppView();
});
app.js:
define([
"jquery",
"underscore",
"backbone"
], function( $, _, Backbone ) {
var AppView = Backbone.View.extend({
el: $( "#main" ),
initialize: function () {
this.render();
},
render: function() {
this.el.html("huzzah!");
}
});
return AppView;
});
You're going to need to shim backbone in order for it to work with requirejs.
From the RequireJS docs:
requirejs.config({
shim: {
'backbone': {
//These script dependencies should be loaded before loading
//backbone.js
deps: ['underscore', 'jquery'],
//Once loaded, use the global 'Backbone' as the
//module value.
exports: 'Backbone'
}
}
});
Related
I've read many answers and followed steps I could ( seems right to me) but still DevTools shows Backbone is not defined. error.
Here's how I use requirejs shim.
<script data-main="js/subject_main.js" src="js/libs/require.js"></script>
subject_main.js
require.config({
paths: {
bootstrap: '../libs/bootstrap.min',
jquery: '../libs/jquery',
underscore: '../libs/underscore',
backbone: '../libs/backbone',
text: '../libs/text',
json2: '../libs/json2',
templates: '../../templates'
},
shim: {
'boostrap':{
deps: ['jquery']
},
'backbone': {
deps: ['jquery', 'underscore'],
exports: 'Backbone'
},
'underscore': {
exports: '_'
}
}
});
require(['subjects', 'json2'], function(app) {
app.initialize();
});
subjects.js
define(['jquery', 'underscore', 'backbone', 'subject_router'], function($, _, Backbone, router) {
return {
initialize: function() {
Backbone.history.start();
}
};
});
subject_router
define([
'jquery',
'underscore',
'backbone',
'models/subject_item_model',
'collections/subjects_collection',
'views/subject_view'
],function($, _, Backbone) {
var AppRouter = Backbone.Router.extend({ ... });
return new AppRouter();
});
Chrome DevTools shows following sequence (order ) of scripts -
As you can see, backbone is loaded at very end. I don't know what's going wrong and where.
backbone.js or underscore.js look fine to me here, and indeed they are being loaded!
The 404s in your dev tool are referring to the source mapping files (underscore.min.map). You might want to look at this post: Missing Javascript ".map" file for Underscore.js when loading ASP.NET web page.
PS: In your subject_router code you have a mismatch on the arguments passed in to the module function.
I'm trying to get Masonry loaded into my app using RequireJS, but it keeps causing backbone to spit out a "object is not a function" error anytime I add it.
Edit: possibly related to this issue.
main.js
require.config({
paths: {
jquery: 'lib/jquery-1.9.1',
underscore: 'lib/underscore-1.5.2',
backbone: 'lib/backbone-1.0.0',
masonry: 'lib/masonry.pkgd'
},
shim: {
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
underscore: {
exports: '_'
}
}
});
require(['app'], function(App){
App.initialize();
});
app.js
define([
'jquery',
'underscore',
'backbone',
'masonry',
'collections/ideas',
], function($, _, Backbone, Masonry, IdeasCollection) {
var IdeasView = Backbone.View.extend({
el: $('#container'),
initialize: function() {
...
},
render: function(){
...
}
});
return IdeasView;
});
To use Masonry as a jQuery plugin with RequireJS, you’ll need to run jQuery bridget.
Check the documentation:
http://masonry.desandro.com/appendix.html#requirejs
You can download bridget here:
https://github.com/desandro/jquery-bridget
Then you can include an run bridget and it should work fine
define([
'jquery'
, 'underscore'
, 'backbone'
, 'config'
, 'app'
, 'jquery.masonry'
, 'jquery.bridget'
], function ($, _, Backbone, Config, App, Masonry, bridget) {
initialize : function () {
bridget('masonry', Masonry);
}
});
Hope it helps!
This is one way you can run it without bridget:
requirejs-config.js:
var config = {
paths: {
"lib-masonry": "Module/js/lib/masonry.pkgd.min"
},
shim: {
"lib-masonry": {
deps: ['jquery', 'jquery/ui']
}
}
}
and then in another module where you want to use it:
define([
'jquery',
'lib-masonry'
], function ($, Masonry) {
$.widget('ModuleNamespace.containerMasonry', {
options: {
},
_create: function() {
var msnry = new Masonry('.grid', {
itemSelector: '.grid__item',
columnWidth: 200
});
// .. code
}
});
return $.ModuleNamespace.containerMasonry;
});
I'm newbie to backbone.js and require.js. Currently I create one backbone project.
Here is app.js code :
define([
'jquery',
'underscore',
'backbone',
'script',
'router'
], function($, _, Backbone, Script, Router){
var initialize = function(){
Router.initialize();
};
return {
initialize: initialize
};
});
Here is main.js:
require.config({
path: {
jquery: 'libs/jquery/jquery-min',
underscore: 'libs/underscore/underscore-min',
backbone: 'libs/backbone/backbone-min',
script: 'libs/scripts/index'
},
shim:{
backbone: ['jquery', 'underscore'],
script: ['jquery'],
enforceDefine: true
}
});
require([
'app',
], function(App){
App.initialize();
});
And the last one is router.js :
define([
'jquery',
'underscore',
'backbone',
'script'
], function($, _, Backbone){
var AppRouter = Backbone.Router.extend({
routes:{
'*actions': 'defaultAction'
}
});
var initialize = function(){
var app_router = new AppRouter;
app_router('route:defultAction', function(actions){
});
Backbone.history.start();
};
return {
initialize: initialize
};
});
I want to add jquery-json library to my project. If in html project, here is my code :
<script type="text/javascript" src="jquery-min.js"></script>
<script type="text/javascript" src="jquery.json-2.4.min.js">
</script>
<script>
function serializeObjToJSON(_obj) {
var _json = $.toJSON(_obj);
return _json;
}
function deserializeJSONToObj(_json) {
var _obj = $.evalJSON(_json);
return _obj;
}
</script>
I want to import the library above and using it in my backbone project. But I have no idea how to do that.
Any help would be much appreciated, thank you.
in your main JS you should add the JSON reference. (put jquery.json-2.4.min.js into lib/ folder)
require.config({
path: {
jquery: 'libs/jquery/jquery-min',
underscore: 'libs/underscore/underscore-min',
backbone: 'libs/backbone/backbone-min',
script: 'libs/scripts/index',
json: 'libs/jquery.json-2.4.min'
}
Then you can add it as a definition into the app.js or any other module.js file which is using it in reference .
define([
'jquery',
'underscore',
'backbone',
'script',
'router',
'json'
], function($, _, Backbone, Script, Router, Json){
//Code
}
Then within your js files you have your reference to json. You can call it by using
Json.method()
for example.. As soon as you write json, it looks for your definition and then reffers to that lib for the functions you called.
So your index.js or whichever end you want to call it will require something like :
define([
'jquery',
'underscore',
'backbone',
'script',
'router',
'json'
], function($, _, Backbone, Script, Router, Json){
serializeObjToJSON: function(_obj) {
var _json = Json.toJSON(_obj);
return _json;
}
deserializeJSONToObj: function(_jsonObject) {
var _returnObj = Json.evalJSON(_jsonObject);
return _returnObj;
}
I'm relatively new to Backbone and RequireJS, so please bear with me. I'm getting an error when I do the following in my collection: _.range(0,10). It's giving me this error:
Uncaught TypeError: Cannot call method 'range' of undefined
Somehow the "_" is not getting resolved when my Collection is loaded. Here's my collection below:
define([
'jquery',
'underscore',
'backbone',
'collections/feed',
'text!/static/templates/shared/display_item.html'
], function($, _, Backbone, FeedCollection, DisplayItem){
debugger; // Added this to test the value of _
var FeedView = Backbone.View.extend({
el: '#below-nav',
initialize: function () {
this.feedCollection = new FeedCollection();
},
feed_row: '<div class="feed-row row">',
feed_span8: '<div class="feed-column-wide span8">',
feed_span4: '<div class="feed-column span4">',
render: function () {
this.loadResults();
},
loadResults: function () {
var that = this;
// we are starting a new load of results so set isLoading to true
this.isLoading = true;
this.feedCollection.fetch({
success: function (articles) {
var display_items = [];
// This line below is the problem...._ is undefined
var index_list = _.range(0, articles.length, 3);
_.each(articles, function(article, index, list) {
if(_.contain(index_list, index)) {
var $feed_row = $(that.feed_row),
$feed_span8 = $(that.feed_span8),
$feed_span4 = $(that.feed_span4);
$feed_span8.append(_.template(DisplayItem, {article: articles[index]}));
$feed_span4.append(_.template(DisplayItem, {article: articles[index+1]}));
$feed_span4.append(_.template(DisplayItem, {article: articles[index+2]}));
$feed_row.append($feed_span8, $feed_span4);
$(that.el).append($feed_row);
}
});
}
});
}
});
return FeedView;
});
I added the debugger line so that I could test the values of all the arguments. Everything loaded fine, except for _. Could this be something wrong with my config.js file?
require.config({
// Set base url for paths to reference
baseUrl: 'static/js',
// Initialize the application with the main application file.
deps: ['main'],
paths: {
jquery: 'libs/jquery/jquery.min',
require: 'libs/require/require.min',
bootstrap: 'libs/bootstrap/bootstrap.min',
text: 'libs/plugins/text',
underscore: 'libs/underscore/underscore',
backbone: 'libs/backbone/backbone',
json: 'libs/json/json2',
base: 'libs/base/base'
},
shim: {
'backbone': {
// These script dependencies should be loaded first before loading
// backbone
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'bootstrap': {
deps: ['jquery'],
exports: 'Bootstrap'
}
}
})
Your help is greatly appreciated. My head is spinning as a result of this error.
Based off the project that I'm working on, you need a shim for underscore as well. Underscore isn't 'exported' per say, so use this instead:
shim: {
'backbone': {
// These script dependencies should be loaded first before loading
// backbone
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'bootstrap': {
deps: ['jquery'],
exports: 'Bootstrap'
},
'underscore': {
exports: '_'
}
}
Seems this might also be 'duplicate' question of Loading Backbone and Underscore using RequireJS - one or two of the answers down the list there is a mention of this setup.
I have an underscore JS template and a jQuery plug-in that depends on the markup that gets rendered after the template is visible, but the problem is when I use jQuery document ready, it doesn't get the HTML that is rendered.
I used domReady but still ain't working, how can I accomplish this probably? This is what I got so far:
main.js
requirejs.config({
baseUrl: 'js/modules',
shim: {
// 'jquery.colorize': ['jquery'],
// 'jquery.scroll': {
// deps: ['jquery'],
// exports: 'jQuery.fn.colorize'
// },
'backbone': {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
'underscore': {
deps: ['jquery'],
exports: '_'
}
},
paths: {
'jquery': '../libs/jquery',
'underscore': '../libs/underscore',
'backbone': '../libs/backbone',
'text': '../libs/text',
'views': '../views',
'templates': '../../templates',
'domReady': '../libs/domReady',
'ui': '../ui'
}
});
requirejs(['homeView', 'ui/placeholder'], function(Main){
Main.initialize();
});
homeView.js
define(['jquery', 'underscore', 'backbone', 'text!templates/home.html'], function($, _, Backbone, homeTemplate){
var HomeView = Backbone.View.extend({
el: $("#application"),
events: function(){
// Empty.
},
initialize: function(){
// Empty.
},
render: function(){
$('body').addClass('pt-dark');
$(this.el).html(_.template(homeTemplate, {}));
}
});
return new HomeView;
});
ui/placeholder.js
requirejs(['domReady', 'jquery'], function(doc, $){
doc(function(){
// Empty should contain the template html at this point.
console.log($('body').html());
});
});
Thanks a lot for help!
Try this:
define(['jquery', 'underscore', 'backbone', 'text!templates/home.html'], function($, _, Backbone, homeTemplate){
var HomeView = Backbone.View.extend({
el: $("#application"),
template: _.template(homeTemplate),
events: function(){
// Empty.
},
initialize: function(){
// Empty.
},
render: function(){
$('body').addClass('pt-dark');
this.$el.html(this.template({})));
jQuery('#the_thing_you_need', this.$el).theFunctionYouNeed();
}
});
return new HomeView;
});
Note that you should define a local attribute to the view called 'template' or something of that sort to store your template in and not re-call _.template every time that you need it.
Also, instead of jQuery(this.el) you can use this.$el.