For multiple page web app in backbone.js there are lots of consideration but here are two which can be useful.
Serving the page : In this, where you want to have your web server route everything to the server route everything to serve the same static page. That me that everything in http://wisdomjobs.com/* will serve /var/www/wisdomjobs.com/index.html. once the static page is loaded, the JS on that page will decide what to do given the url
Push State : You can still use backbone routing to do your routing, but don’t use hashbangs. This will allow you to navigate to URLs without actually needing a page refresh.
It gets the current value of an attribute from the model but returns the HTML-escaped version of a model’s attribute. It is helpful in preventing XSS attacks, if you are interpolating data from the model into HTML.
The main component of Backbone.js are:
You can set attributes of a model in two ways. Using constructor parameter or .set().
See the below example:
var myObj = new MyClass({ attrib1: "Thomas", attrib2: 67});
//Or we can set afterwards, these operations are equivalent
var myObj = new MyClass();
myObj.set({ attrib1: "Thomas", attrib2: 67});
The attributes property is the internal hash containing the model’s state, usually a form of the JSON object representing the model data on the server. It is often a straightforward serialization of a row from the database.
Below are some practices you should follow while working with Backbone models:
Get all the Current Attributes
obj.attributes gives a direct reference to the attributes and you should be careful when playing with it. Best practice would suggest that you use .set() to edit attributes of a model to take advantage of backbone listeners.
var person = new Person({ name: "Thomas", age: 67});
var attributes = person.toJSON(); // { name: "Thomas", age: 67}
/* This simply returns a copy of the current attributes. */
var attributes = person.attributes;
Validate Data Before You Set or Save It
Always implement validate() method so that Backbone validates the input before setting any attribute value. It ensures that invalid data is not stored on your server.
Person = Backbone.Model.extend({
// If you return a string from the validate function,Backbone will throw an error
validate: function( attributes ){
if( attributes.age < 0 && attributes.name != "Dr Manhatten" ){
return "You can't be negative years old";
}
},
initialize: function(){
//Bind callback for error event
this.bind("error", function(model, error){
// We have received an error, log it, alert it or forget it <img alt=":)" class="wp-smiley" src="http://synvistech.com/blogs/wp-includes/images/smilies/simple-smile.png" style="height: 1em; max-height: 1em;" />
alert( error );
});
}
});
var person = new Person;
person.set({ name: "Mary Poppins", age: -1 });
// Will trigger an alert outputting the error
var person = new Person;
person.set({ name: "Dr Manhatten", age: -1 });
You can get the value of model attribute by using .get() method.
See the example below:
//Set attributes
var obj = new MyClass({ attrib1: "Attribute1", attrib2: 50});
//Get attributes
var attrib1 = obj.get("name"); // "Attribute1"
var attrib2 = obj.get("age"); // 50
To make synchronization process of views and models together, ModelBinder class is used.
var Song = Backbone.Model.extend({
defaults: {
name: "Not specified",
artist: "Not specified"
},
initialize: function(){
console.log("Music is the wer");
}
});
var Album = Backbone.Collection.extend({
model: Song
});
var song1 = new Song({ name: "How Bizarre", artist: "OMC" });
var song2 = new Song({ name: "Sexual Healing", artist: "Marvin Gaye" });
var song3 = new Song({ name: "Talk It Over In Bed", artist: "OMC" });
var myAlbum = new Album([ song1, song2, song3]);
console.log( myAlbum.models ); // [song1, song2, song3]
An ordered set of models are represented by Backbone.js collections. Any event in model will trigger an event in collection directly. For example, you can bind “change” event to be notified in a case when any model in the collection has been modified.
Model.cid works as a unique identifier. It is a special property of models, the cid or client id is automatically assigned to all models when they are first created. This property is useful when the model is not saved to the server, but needs to be visible in the UI. It takes the from c1,c2….
In case of Dynamic Routing, you can use variables in the route. For example, you might want to retrieve a post with a variable id with a friendly URL string. You can specify variable name in the route as :variablename in dynamic routing.
<script>
var AppRouter = Backbone.Router.extend({
routes: {
"posts/:id": "getPost",
"*actions": "defaultRoute" // Backbone will try to match the route above first
}
});
// Instantiate the router
var app_router = new AppRouter;
app_router.on('route:getPost', function (id) {
// Note the variable in the route definition being passed in here
alert( "Get post number " + id );
});
app_router.on('route:defaultRoute', function (actions) {
alert( actions );
});
// Start Backbone history a necessary step for bookmarkable URL's
Backbone.history.start();
</script>
The configuration options available are:
When ever a model’s data is returned by the server, in fetch and save , this data is called parse. It is called by Backbone whenever a collection’s models are returned by server, in fetch.
A function is called when model’s attribute is copied to an html element or when an html element value is copied into a model’s attribute, this function is referred as Converter in Backbone.js
When ever an application want to change their URL fragment in order to provide bookmarkable and shareable URLs for an Ajax heavy application, backbone.js router is used.
Backbone.js is required in following condition:
It returns a shallow copy of the model’s attribute for JSON stringification. This function is used for persistence, serialization and for augmentation before being sent to the server. This does not return a JSON string.
All attributes of a model can have listeners bound to them to detect changes to their values. In our initialize function, we are going to bind a function call everytime we change the value of our attribute. In this case, if the name of our “person” changes, we will alert their new name. Syntax for attaching callback to change event of attribute is this.on(“change”, function(model){});.
See the example below:
Person = Backbone.Model.extend({
defaults: {
name: 'Fetus',
age: 0
},
initialize: function(){
alert("Below we are attaching callback to change event of 'name' attribute");
this.on("change:name", function(model){
var name = model.get("name"); // 'Stewie Griffin'
alert("Changed my name to " + name );
});
}
});
var person = new Person({ name: "Thomas", age: 67});
person.set({name: 'Stewie Griffin'}); // This triggers a change and will alert()
You can define views in Backbone.js similar to Backbone models. See example below:
SearchView = Backbone.View.extend({
initialize: function(){
alert("WOW! SearchView has been defined.");
}
});
// The initialize function is always called when instantiating a Backbone View.
// Consider it the constructor of the class.
var search_view = new SearchView();
//You can specify el property for the view or else it will create empty div and assign it
<div id="search_container"></div>
var search_view = new SearchView({ el: $("#search_container") });
Backbone collections are simply an ordered set of models.
Typically, your collection will only use one type of model but models themselves are not limited to a type of collection.
var Song = Backbone.Model.extend({
initialize: function(){
console.log("Music is the wer");
}
});
var Album = Backbone.Collection.extend({
model: Song
});
If we instantiate a model with an id, Backbone.js will automatically perform a GET request to the urlRoot + ‘/id’ using fetch() method. (conforming to RESTful conventions)
If the id attribute of the model is null, Backbone.js will send a POST request to the urlRoot of the server using save() method.
If the id attribute of the model is not null, Backbone.js will send a PUT request instead of a POST request using save() method.
If a model has an id we know that it exists on the server, so if we wish to remove it from the server we can call destroy() method. destroy will fire off a DELETE /user/id (conforming to RESTful conventions).
See the example below for all these above operations:
// Here we have set only the `id` of the model so it will call fetch() method.
var user = new Usermodel({id: 1});
// The fetch below will perform GET /user/1
// The server should return the id, name and email from the database
user.fetch({
success: function (user) {
alert(user.toJSON());
}
})
// Here we have set all the attributes, along with id,
// of the model so it will call save() method with PUT
var user = new Usermodel({
id: 1,
name: 'Thomas',
email: 'myemailid@domain.com'
});
// Let's change the name and update the server
// Because there is `id` present, Backbone.js will fire
// PUT /user/1 with a payload of `{name: 'Davis', email: 'myemailid@domain.com'}`
user.save({name: 'Davis'}, {
success: function (model) {
alert(user.toJSON());
}
});
// Here we have set all the properties of model.
var user = new Usermodel({
id: 1,
name: 'Thomas',
email: 'thomasalwyndavis@gmail.com'
});
// Because there is `id` present, Backbone.js will fire
// DELETE /user/1
user.destroy({
success: function () {
alert('Destroyed');
}
});
Models are used to represent data from your server and actions you perform on them will be trlated to RESTful operations. The id attribute of a model identifies how to find it on the database usually mapping to the surrogate key.
Suppose you have a table Users with columns id, name, email and you want to save the model back on server when user clicks save button. If the id attribute of the model is null, Backbone.js will send a POST request to the urlRoot of the server. For this,
see the example below:
var UserModel = Backbone.Model.extend({
urlRoot: '/user', //RESTful API relative path
defaults: {
name: '',
email: ''
}
});
var user = new UserModel();
// Notice that we haven't set an `id`. In case of update operation, we need to pass 'id' as well.
var userDetails = {
name: 'Thomas',
email: 'youemailid@domain.com'
};
// Because we have not set a `id` the server will call
// POST /user with a payload of {name:'Thomas', email: 'youremailid@domain.com'}
// The server should save the data and return a response containing the new `id`
user.save(userDetails, {
success: function (user) {
alert(user.toJSON());
}
})
The most powerful capabilities of ModelBinder class is that it enables you to define scope when you create your bindings using jQuery.
Backbone events is a module that can be mixed in to any object, giving the object the ability to bind and trigger custom named events. Events are not declared before they are bound to any object . Events reflects the state of the model.
We can write the methods which contain the business logic.
See the example below:
Person = Backbone.Model.extend({
defaults: {
name: 'Fetus',
age: 0,
child: ''
},
initialize: function(){
alert("This class has adop() method which contains business logic to set new child.");
},
adopt: function( newChildsName ){
this.set({ child: newChildsName });
}
});
var person = new Person({ name: "Thomas", age: 67, child: 'Ryan'});
person.adopt('John Resig');
var child = person.get("child"); // 'John Resig'
Backbone.js models are object and core of backbone.js. It contains an array of attributes and listens for events. To represent your data, Backbone provides a model object. For example, you have a to do list, you would have a model representing each item on that list.
Use the “events” attribute of Backbone.View. Remember that event listeners can only be attached to child elements of the “el” property.
See example below:
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
var template = _.template( $("#search_template").html(), {} );
this.$el.html( template );
},
//Attach listener to click event of the search button
events: {
"click input[type=button]": "doSearch"
},
doSearch: function( event ){
// Button clicked, you can access the element that was clicked with event.currentTarget
alert( "Search for " + $("#search_input").val() );
}
});
When you want to remove the validation binding on the model or all models , removing all events hooked up on the collection, you can use Unbinding function.
For example : Backbone.Validation.Unbind(view) [ This will remove the validation binding]
See the below example:
<script type="text/template" id="search_template">
<label>Search</label>
<input type="text" id="search_input" />
<input type="button" id="search_button" value="Search" />
</script>
<div id="search_container"></div>
<script type="text/javascript">
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
// Compile the template using underscore
var template = _.template( $("#search_template").html(), {} );
// Load the compiled HTML into the Backbone "el"
this.$el.html( template );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</script>
Yes, we can set default values for the model attributes.
See the example below:
MyClass = Backbone.Model.extend({
defaults: { //sets default values
attrib1: 'Default Attribute1 Value',
attrib2: 0
},
initialize: function(){
alert("It is so easy to set default values. Isn't it?");
}
});
you are required following three js files to setup a working environment for backbone
In your application put these files within js folder and use it in your index.html page
Backbone.js is a JavaScript client-side (front end) framework, which helps to organize your code and makes it easier to develop single page applications. It allows you to structure JavaScript code in an MVC (Model, View , Controller) fashion.
Model: It is a part of your code that populates and retrieves the data.
View: It is the HTML representation of this model.
Controller: It enables you to save your javascript application via a hashbang URl.
When Backbone wants to save or read a model to the server it calls out a function called as Backbone.sync.
Backbone routers are used for routing your applications URLs when using hash tags(#). In the traditional MVC sense, they don’t necessarily fit the semantics and if you have read “What is a view?” it will elaborate on this point. Though a Backbone “router” is still very useful for any application/feature that needs URL routing/history capabilities.
Defined routers should always contain at least one route and a function to map the particular route to.
Routes interpret anything after “#” tag in the URL. All links in your application should target “#/action” or “#action”. (Appending a forward slash after the hashtag looks a bit nicer, e.g. http://wisdomjobs.com/#/user/help).
<script>
var AppRouter = Backbone.Router.extend({
routes: {
"*actions": "defaultRoute" // matches http://wisdomjobs.com/#anything-here
}
});
// Initiate the router
var app_router = new AppRouter;
app_router.on('route:defaultRoute', function(actions) {
alert(actions);
})
// Start Backbone history a necessary step for bookmarkable URL's
Backbone.history.start();
</script>
Models are used to represent data from your server. Model in BackboneJs contains:
MyClass = Backbone.Model.extend({
initialize: function(){
alert("I will initialize the model when it is created. I am like constructor.");
}
});
var myObj = new MyClass();
Backbone view is a Javascript object that manages a specific DOM element and descendants.
You can access template variables with <%= %>.
<script type="text/template" id="search_template">
<label><%= search_label %></label>
<input type="text" id="search_input" />
<input type="button" id="search_button" value="Search" />
</script>
<div id="search_container"></div>
<script type="text/javascript">
SearchView = Backbone.View.extend({
initialize: function(){
this.render();
},
render: function(){
//Pass variables in using Underscore.js Template
var variables = { search_label: "My Search" };
// Compile the template using underscore
var template = _.template( $("#search_template").html(), variables );
// Load the compiled HTML into the Backbone "el"
this.$el.html( template );
},
events: {
"click input[type=button]": "doSearch"
},
doSearch: function( event ){
// Button clicked, you can access the element that was clicked with event.currentTarget
alert( "Search for " + $("#search_input").val() );
}
});
var search_view = new SearchView({ el: $("#search_container") });
</script>
setElement function is used when Backbone view has to be applied to a different DOM element.
BackboneJs is a JavaScript framework which allows the developers to make their life easier by providing the below features:
Model:– Store data
Model can have listeners bound to them to detect changes to their values
Collection: Group of models
View: Represents UI
Routing: Manages how to show appropriate view when request through URL