RequireJS / BackboneJS app - Need suggestion on adding dependency - backbone.js

I am developing an app using backboneJS/requireJS. I have identified around 20 views, and for all the views I am using jquery, backbonejs and underscorejs. So my first three dependencies are always these three.
define([
'jquery',
'underscore',
'backbone',
.... ], function($, _, Backbone, ..){
.....
});
Is there a way i can skip and say somewhere at global level to include these three in all modules, so that I can avoid writing them redundantly in all files?

There are a few ways to do this. One is to wrap define in your own myDefine (or whatever):
myDefine = function(dependencies, callback) {
var defaults = ['jquery', 'underscore', 'backbone'],
combined = defaults.concat(dependencies);
return define(combined, callback);
};
myDefine(['MyView'], function($, _, Backbone, MyView) {
// do stuff
});
But this obviously still requires you to specify the objects in your callback. So a better option might be to attach $, _, and Backbone to your application namespace (if you don't want them to be global). Then you could do something like this:
myDefine = function(dependencies, callback) {
var defaults = ['jquery', 'underscore', 'backbone'];
if (myApp.$ && myApp._ && myApp.Backbone) {
define(dependencies, callback);
} else {
require(defaults, function($, _, Backbone) {
myApp.$ = $;
myApp._ = _;
myApp.Backbone = Backbone;
define(dependencies, callback);
}
}
};
myDefine(['MyView'], function(MyView) {
// use myApp.$, myApp._, myApp.Backbone
});
If you don't care about namespacing, you could just do the above without the myApp steps and let the libs stay in window.
Note that all above is untested.
The simpler option of course is simply to load jQuery, Underscore, and Backbone synchronously before any of your modules.

Related

Issue related to rendering multiple views through a single view

Question Updated
I am implementing a search and result for the same in the same page. i
have two seperate html views and views for search and result.
Here is what is happening..
From my router the below view is loaded. This view will load two other views called search and result. I have included the respective html views in the seperate views. but when i run the proj, it displays nothing.
Am i rendering the view in this file wrong ??
if i am rendering it wrong can somebody please tell me where is the mistake and how to rectify it ??
should i include the respective html templates of search and result also in this file ??
views.driver.search.js :
define(
[ 'jquery',
'underscore',
'backbone',
'app/models/model.driver',
'app/collections/collection.driver',
'app/models/model.driver.searchform',
'app/dashboard/views.driver.searchForm',
'app/models/model.driver.searchresult',
'app/dashboard/views.driver.searchResults',
],
function ($, _, Backbone, DriverModel,SearchResultCollection ,searchFormModel, searchFormView, SearchResultModel,SearchResultView) {
var DriverSearchView = Backbone.View.extend({
el: $('#content'),
initialize: function(){
this.render();
},
render: function () {
// var compiledTemplate = _.template(searchFormTemplate, {});
// this.$el.html(compiledTemplate);
this.searchFormInitModel = new searchFormModel();
var searchformView = new searchFormView({model:this.searchFormInitModel});
this.$("#content").html(searchformView.render());
var driver1 = new DriverModel({id:1,firstName:"driver1",lastName:'last',dob:'12/12/12001',});
var driver2 = new DriverModel({id:2,firstName:"driver2",lastName:'last',dob:'12/12/12001',});
var driver3 = new DriverModel({id:3,firstName:"driver3",lastName:'last',dob:'12/12/12001',});
var driver4 = new DriverModel({id:4,firstName:"driver3",lastName:'last',dob:'12/12/12001',});
this.searchResultCollection= new SearchResultCollection([driver1, driver2, driver3, driver4]);
var searchResultView = new SearchResultView({el:this.$el.find("#searchResult"),collection:this.searchResultCollection});
this.$("#content").html(searchResultView.render());
//this.$el.find("#searchResult").html(searchResultView.render());
}
}); // Our module now returns our view
return DriverSearchView;
});
I don't see an issue with your workflow. Reason you are not seeing your console.logs, is because you are returning an object literal containing your initialize function without actually calling the function. Is there a reason you need to return an object from your initialize module?
Anyhow, I am not entirely sure how you calling your app.js file, but try the following if you do not need to return an object back from your initialize module
define(
[
'jquery',
'underscore',
'backbone',
'app/router',
// 'datatable'
],
function ($, _, backbone, router){ //,datatable) {
var initialize = (function () {
console.log("App1");
debugger;
console.log("App2");
router.initialize();
console.log("App3");
})();
// Depending what you want to do here, you could just
// console.log("Router initialized...");
// router.initialize();
});

RequireJS/Backbone: Getting view returned from require

Here is my view:
define([
'jquery',
'underscore',
'backbone',
'models/tableModel',
'collections/tablesCollection',
'views/tablesView'
], function($, _, Backbone, tableModel, tablesCollection, tablesView) {
require(['collections/tablesCollection'], function(tablesCollection) {
var t = new tablesCollection(null, {url: 'main-contact'});
var tables = new tablesView({ collection: t, template: 'main-contact-template'});
tables.url = 'main-contact';
return tables; // <!-- returns view, tables can be console.log'ed
});
console.log(tables); // <!-- tables is not defined
});
How do I get the tables within the require statement so that is accessible where the console.log is? This seems to be where I need to return the view from, so I can use it in my route:
app_router.on('route:index', function(){
require(['views/tables/mainContactView'], function(mainContactView) {
console.log(mainContactView); // <!-- undefined, unless some value is returned from where the console.log() is above
$('#web-leads').html(mainContactView.render().el);
});
});
If I put return 'test' where the console.log(tables) is, I can console.log() it in my route. So I assume that's where I need to return the view from. How do I pass that data out? Right now, even with a return statement, my view is undefined. I need to get the view out of the require. How do I do that?
You've already loaded collection/tablesCollection in define, so you don't have to do another require to get it loaded.
You can simply the definition of the View as this:
define([
'jquery',
'underscore',
'backbone',
'models/tableModel',
'collections/tablesCollection', // You've already required tablesCollection here.
'views/tablesView'
], function($, _, Backbone, tableModel, tablesCollection, tablesView) {
var t = new tablesCollection(null, {url: 'main-contact'});
var tables = new tablesView({ collection: t, template: 'main-contact-template'});
tables.url = 'main-contact';
return tables;
});

require.js / js file loads before DOM loaded

I am new in MVC framework like backbone.js. I am trying to make an application using backbone.js, require.js and underscore.js. I also added jQuery UI. There is a js file named widget.js which actually adjusts widgets like fixing position, firing some events when window re-sizes, firing ui events like button(), tab() etc.
Now the problem is when I open a page using a url directly (like http:://localhost/web/#/login), everything works well. But when I open that page from another page using navigation menu, there occurs a mass. The page looks ugly. I think this is because when I load the page using a url than widget.js loads after DOM is loaded but when I open the page using navigation, then widget.js loads before DOM is loaded. Wasted 3 days to find a solution .But no luck. Here is the code..
define([
'jQuery',
'Underscore',
'Backbone',
'text!templates/loginForm.html',
'text!templates/home.html',
'libs/custom/widget',
], function($, _, Backbone, loginForm, homeTemplate, widget){
var loginView = Backbone.View.extend({
el: $("#page"),
status: 'Failed',
serverMsg:'Mail doesn\'t match',
events:{
"click .login":"login"
},
isLogedIn:function(){
if(this.status=='Failed' || this.status==''){
console.log("error");
}else{
console.log("succss");
}
},
login:function(e){
e.preventDefault();
var info = $(".loginForm").serialize();
var url = 'http://rest.homeshop.dev/login/';
var This = this;
$.ajax({
url:url,
type:"POST",
data:info,
success:function(data){
data = $.parseJSON(data);
This.serverMsg = data.msg;
This.status = data.status;s
This.isLogedIn();
}
});
return false;
},
initialize: function(){
},
render: function(){
var data = {};
var compiledTemplate = _.template( loginForm, data);
this.el.find('.carrier').html(compiledTemplate);
}
});
return new loginView;
});
Also I did not added jquery Ui library here as I have added that library in application.js .Here is the codes for application.js
define([
'jQuery',
'Underscore',
'Backbone',
'router',
'libs/custom/jqueryUi-min',
'libs/custom/widget',
'libs/custom/layoutSwitcher'
], function($, _, Backbone, Router){
var initialize = function(){
Router.initialize();
}
return {
initialize: initialize
};
});
Can any one help me ?
I think what you want is the domReady! plugin. http://requirejs.org/docs/api.html#pageload
define(['jQuery', 'Backbone', 'Router', 'libs/custom/widget', 'domReady!']
, function($, Backbone, Router, widget, dom) {
//execute your code knowing that the DOM has loaded.
}
)
Hope this helps!

Stackmob with requires.js

I'm laying out the basic structure and just started to create models. The issue is that the reference to the initialized Stackmob is lost within the model.
main.js
require(['modernizr','jquery','backbone', 'underscore', 'routers/router', 'stackmob'], function(Modernizr, $, Backbone, _, Router, Stackmob) {
StackMob.init({
appName: {appName},
clientSubdomain: {clientSubdomain},
apiVersion: 0
});
// Instantiates a new Router
this.router = new Router();
});
Model.js
define(['jquery', 'backbone', 'stackmob', 'models/business'], function($, Backbone, Stackmob, Business) {
var BusinessesCollection = StackMob.Collection.extend({
model: Business,
// Model Constructor
initialize: function() {
}
});
// Returns the Model class
return BusinessesCollection;
});
How can I get the initialized StackMob object to be accessible to the model module?
Introduce a sort of instance of StackMob?
my-stackmob.js
define(['stackmob'], function(StackMob) {
StackMob.init({
appName: {appName},
clientSubdomain: {clientSubdomain},
apiVersion: 0
});
// return a particular StackMob that we've initialised
return StackMob;
});
main.js
(would not appear to use StackMob directly any more, based on your example code)
require(['modernizr','jquery','backbone', 'underscore', 'routers/router'], function(Modernizr, $, Backbone, _, Router) {
// Instantiates a new Router
this.router = new Router();
});
Model.js
(uses my-stackmob)
define(['jquery', 'backbone', 'my-stackmob', 'models/business'], function($, Backbone, Stackmob, Business) {
var BusinessesCollection = StackMob.Collection.extend({
model: Business,
// Model Constructor
initialize: function() {
}
});
// Returns the Model class
return BusinessesCollection;
});

How to combine Box2dWeb and RequireJs together

I built file structure for javascript game using RequireJs and Backbone. Now I have problem to combine it with Box2DWeb.
// Filename: game/controller/arena.js
define([
'jquery',
'underscore',
'backbone',
'_69_',
'game/controller/object',
'game/model/arena',
'game/view/arena',
'box2d'
], function($, _, Backbone, _69_, Object, Model, View, Box2D){
var ArenaController = Object.extend ({
init : function (){
this._super(Model, View);
this.world = new b2World(
new b2Vec2(0, 10) //gravity
, true //allow sleep
);
this.appView;
this.loops=0;
},
start : function (){
_69_.l('start')
},
update :function (){
_69_.l('update')
},
stop : function (){
_69_.l('stop')
}
});
return new ArenaController;
});
But in console I get that b2World is not defined. What i should do to get it work?
I dont know box2d but box2world does indeed not exist in that context unless it is a global object.
I presume here that you will need its namespace, if it is included in the box2d reference you defined in the required.js dependencies you might use
new Box2D.b2World(...);
you should try to including "box2D" in the require of your main.js file. Box2D will load as a global object which you can use later.
require([
'app',
'box2d'
], function(app){
app.init();
});
You shouldn't mention it in the function or you could list it as "ignore":
require([
'app',
'box2d'
], function(app, ignore){
app.init();
});
In the Chrome console, you could type Box2D and you should see it pop up as a global object. Once you know its global, you can start using it.
Then in your ArenaController you can list "box2d" in the define array but not in the function:
define([
'jquery',
'underscore',
'backbone',
'_69_',
'game/controller/object',
'game/model/arena',
'game/view/arena',
'box2d'
], function($, _, Backbone, _69_, Object, Model, View) {
var ArenaController = Object.extend ({
init : function (){
this._super(Model, View);
var b2World = Box2D.Dynamics.b2World; //Box2D should be available as a global
this.world = new b2World(
new b2Vec2(0, 10) //gravity
, true //allow sleep
);
this.appView;
}
});
return new ArenaController;
});

Resources