Using Backbone.js View as Require.js Dependency - javascript

How can I include a view from another file (e.g. Views.js) in a JavaScript file loaded as a Require.js module? I receive a "Uncaught TypeError: object is not a function" error when I try to instantiate myView.
define([
'jQuery',
'Underscore',
'Backbone',
'src/Views'
], function ($, _, Backbone, myView) {
new myView ({ });
});

Do your "src/views.js" have a return value?
some like this:
define(['underscore', 'backbone'], function(_, Backbone) {
var view = Backbone.View.extend({
......
});
return view; //the return value is essential
});

Related

Unexpected behavoiur of define of requirejs

This code is working
define([
'jquery',
'underscore',
'backbone'
], function($, _, Backbone,home_template) {
var HomeView = Backbone.View.extend({
render: function() {
alert('abcd');
}
});
return HomeView;
});
this code is not working
define([
'jquery',
'underscore',
'backbone',
'text!modules/home/home_template.html'
],
function($, _, Backbone,home_template) {
var HomeView = Backbone.View.extend({
render: function() {
alert('abcd');
}
});
return HomeView;
});
My directory structure is like webroot/modules/home/home_template.html
What can be the problem ??
Thanks
Problem might be in two possible places:
1) Error in path(u can check in in fireBug or any other tool in network tab, look for 404 errors). It might be template or some other scripts placed inn wrong folder.
2) Error in template syntax - in case of underscore be sure your template wrapped in <script type="template">.

backbone loaded with requirejs shim but still Backbone undefined error

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.

loading backbone plugins with requirejs

I was wondering how I could load backbone plugins with require.js I currently have this in my main.js
(function() {
'use strict';
require.config({
shim: {
underscore: {
exports: '_'
},
backbone: {
deps: ['underscore', 'jquery'],
exports: 'Backbone'
},
deepModel: {
deps: ['underscore', 'backbone']
}
},
paths: {
jquery: 'lib/jquery/jquery',
underscore: 'lib/underscore/underscore',
backbone: 'lib/backbone/backbone',
text: 'lib/requirejs-text/text',
deepModel: 'lib/deep-model/deep-model.min'
},
In my model I have something like this
var myapp = myapp|| {};
(function() {
'use strict';
define([
'jquery',
'underscore',
'backbone',
'deepModel',
], function($, _, Backbone) {
myapp.model= new Backbone.DeepModel.extend({
defaults: {
},
urlRoot: '/users',
For some reason the above does not seem to work as expected. I think I am missing something but not sure what that is. I am using the backbone deep model plugin.
This is the error I get in the debugger
Uncaught TypeError: Object [object Object] has no method 'apply'
Add DeepModel to your scope in function signature:
define([
'jquery',
'underscore',
'backbone',
'deepModel',
], function($, _, Backbone, **DeepModel**)
It might make your life easier if you use the AMD-compatible version of backbone and underscore. By default, they do not support AMD.
https://github.com/amdjs/backbone
https://github.com/amdjs/underscore

Import and using javascript library in backbone.js project

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;
}

RequireJs: Wrong module order

I got following router.js:
define(['jquery', 'underscore', 'backbone', 'views/settings/index'], function($, _, Backbone, SettingsView) {
var Router = Backbone.Router.extend({
container: $('div.main'),
routes: {
"settings": "settings"
, "settings/:query": "settings"
},
settings: function(query) {
this.container.html(SettingsView.render().el);
}
});
if (Router._instance) return Router._instance;
Router._instance = new Router();
return Router._instance;
});
The router gets called in the main.js filed which is marked as first dependency in the requirejs config:
define(['jquery', 'underscore', 'backbone', 'router'], function($, _, Backbone, router) {
// ajax settings (sent cors cookies)
$.ajaxSetup({ xhrFields: { withCredentials: true } });
// register master router
window.router = router;
// start backbone history
Backbone.history.start({ root: "/" });
});
In some view I now want to do:
define(['jquery', 'underscore', 'backbone', 'router'], function($, _, Backbone, router) {
var View = Backbone.View.extend({
initialize: function() {
router.on('route:settings', this.change, this);
},
change: function(query) {
// load some new content for example
}
});
return View;
});
Than I am getting this error message:
Uncaught TypeError: Cannot call method 'on' of undefined
UPDATE:
I added a console.log to each module. So I know in which order the modules are executed. I mentioned that requirejs has the wrong order:
view.js -> main.js -> router.js
instead of:
router.js -> main.js -> view.js
Let see how I can solve this
UPDATE2:
I now wrapped the router event binding part into a setTimeout loop:
setTimeout(function() {
window.router.on('route:settings', this.select, this);
}.bind(this), 20);
And see there it works!
This truly just is a fix but nevertheless a fix :)
Why are you trying to create a singleton instance on your router?
Requirejs resolves every module only once as far as I understand and
as far as I would expect from any decent module loader.
#router.js
define(['jquery', 'underscore', 'backbone', 'views/settings/index'],
function($, _, Backbone, SettingsView) {
//your code omitted ...
//no need to do this
//if (Router._instance) return Router._instance;
//Router._instance = new Router();
//return Router._instance;
//this should work as well and give you a "singleton" instance
return new Router();
});
please check if the names/path you have given to requirejs.config() is correct. I have hit the wall hard a few times because I had a slight typo. requirejs doesnt return any errors on such cases but sadly only undefined.
If you are dead sure that there is no typo I'd try to include main.js as an explicit dependency on the definition of your view.
I think you need to return a reference to the Router object at the end of the first define.
define(['jquery', 'underscore', 'backbone', 'views/settings/index'], function($, _, Backbone, SettingsView) {
var Router = Backbone.Router.extend({
container: $('div.main'),
routes: {
"settings": "settings"
, "settings/:query": "settings"
},
settings: function(query) {
this.container.html(SettingsView.render().el);
}
});
var Singletonizer = function(Singleton) {
if (Singleton._instance) return Singleton._instance;
Singleton._instance = new Singleton();
Singletonizer(Singleton);
};
return Singletonizer(Router);
});

Categories