Escolar Documentos
Profissional Documentos
Cultura Documentos
js
Shubh Dasgupta, 3 Jul 2014
4.80 (4 votes)
Introduction
Learning backbone.js for basic create, read, update and delete operations. We will create a basic
application which would help us understanding how to code using backbone.js.
What is Backbone.js
When ever we are working with javascript application we tend to put huge effort structuring the
code and putting the right peice at right place. Which actually may or may not be very
maintainable or scalable. From the backbone official site -
It's all too easy to create JavaScript applications that end up as tangled piles of jQuery selectors
and callbacks, all trying frantically to keep data in sync between the HTML UI, your JavaScript
logic, and the database on your server. For rich client-side applications, a more structured
approach is often helpful.
Now there comes Backbone.js. It is a very light framework which allows you to structure your
application in MV* fashion. MV stands for the basic Model and Views what we have in general
terms. But whats important is *. Frankly, I am not the developers behind Backbone so its hard to
assume that it fits closely towards MVC framework. I assume it to be Controller that in this case
allows you to save the state of your javascript application via a hashtag url. More Details from
Stackoverflow
Example
The very first example which strikes me of is Gmail. Where huge chunks of data is being
downloaded one you are logging in. Then things remains sweet and simple and the background
processes takes the charge. There is never a whole page refresh that takes place. Awesome!
Note
I will be ignoring the backed code as of now. Assuming we have ready api for
Create/Read/Update/Delete.
In this tutorial, I have used ASP.NET MVC API for the CRUD operations and toastr for
notification's. I am a huge fan of this lib, it's just awesome.
What we will do
We will try to create an application that will allow Creation of user, Displaying list of users, Editing
specific user and Deleting specific user.
bundles.Add(new ScriptBundle("~/bundles/backbone").Include(
"~/Scripts/underscore.js",
"~/Scripts/backbone.js"));
// existing code
}
Assuming the above class and we will proceed with client side scripting. You can create your
CRUD api's.
Now, we are creating routes for Listing/Edit/Create of a User. When our url is:
We will be displaying user details screen which will be used for creating a user i.e. we need to
display Create page for user.
We will be displaying user details screen with populated data which will be used for
editing/updating a user.
Now, we define the routes as above, what it will do is, when the hashtag changes in the url the
corresponding route defination will get triggered. We will come back to this section very soon.
Run your application to check if throws any error in console. Change the url to /# or /#create
or/#edit/1, you should see corresponding console statements being printed.
Creating Model
Models are the heart of any JavaScript application, containing the interactive data as well as a
large part of the logic surrounding it: conversions, validations, computed properties, and access
control. You extend Backbone.Model with your domain-specific methods, and Model provides a
basic set of functionality for managing changes.
So without wasting much time, let's create a User Model for our Backbone.
Creating Collection
What the official's say:
Collections are ordered sets of models. You can bind "change" events to be notified when any
model in the collection has been modified, listen for "add" and "remove" events, fetch the
collection from the server, and use a full suite of Underscore.js methods.
Any event that is triggered on a model in a collection will also be triggered on the collection
directly, for convenience. This allows you to listen for changes to specific attributes in any model
in a collection, for example: documents.on("change:selected", ...)
Backbone collection are collection of model's, no doubt it has much more in it. It has more or less
than 28 Underscore methods which support it and allows you keep a watch on them and do
necessary operations when something gets modified or changed. Along with that, its supports
RESTful API's . Awesome!!
Simple and sweet code. We provide our our previously created model and default API which is
ready to return List<User> . you could even try and hardcode you data in case your feeling lazy
to create a backend. All is fine.
Creating View
Backbone views are almost more convention than they are code — they don't determine
anything about your HTML or CSS for you, and can be used with any JavaScript templating
library. The general idea is to organize your interface into logical views, backed by models, each
of which can be updated independently when the model changes, without having to redraw the
page. Instead of digging into a JSON object, looking up an element in the DOM, and updating
the HTML by hand, you can bind your view's render function to the model's "change" event —
and now everywhere that model data is displayed in the UI, it is always immediately up to date.
Before we jump for creting a view, lets first decide our el element. The "el" property references
the DOM object created in the browser. Every Backbone.js view has an "el" property, and if it not
defined, Backbone.js will construct its own, which is an empty div element.
Goto the page where you want to render your user listing page and add a div tag specifying the
class name or id. In my case I have removed the Home/Index.cshtml code and added the below
line:
<div class="user-management"></div>
We are done setting up the element. Let's come back to creating a view which will render the
data.
What I am doing is, I have created a Backbone View having an 'el' property which would hold the
reference to the DOM object created. Secondly, the "render()" function will load our template
into the view's "el" property using jQuery. This method is responsible to fetch the data and
create a template with the data fetched from server(render method should not have the logic for
fetching data from server, we have ways to refactor it, as of now we can live with that). Now the
question comes what is:
Creating Template
Now creating a template would be straight forward, if you have worked with Knockout or Angular
then you would be able to relate it well. In case you have not... No worries... Have a look at the
template:
The underscore template's is a <script> tag with type as "text/template", which actually prevents
the browser from rendering it at first shot. It is not a script that the browser can understand, and
so the browser will simply ignore it. You can put anything here which can be used as a template.
You can use many other libraries like Handlebar/Mustache etc.
</script>
We are almost set with creating a User Model, then creating a User Collection of it. Then we have
created a view which would create an object of User Collecton and fire a fetch request. When the
API return's the data, we are getting our template and binding the data to it. Finally, display it.
Lastly, we need to call our render method from the /# route(our default route). So let jump back
a little where we had:
Run your application to check if throws any error in console. If all is fine the you should be able
to see the list of user's from the database.
Note: In case you are not then open the network tab and check the response you'r getting from
the api. Check the fields which the api is returning and match the properties with what is defined
in the template.
Creation of Users
Now, when we are all set to display list of user's then lets actually create a user and update the
database. Come back to the listing application and check whether user got created or now.
When you click on the link Create User, you would see the /#create getting appended tho the url
and console would give you back "Display Create Page". So we need to start writing our code
there. Before that we need a Create View which would be responsible to display our user model.
Let's start with creating our user view. We would be using the same view for Create and Update.
}
});
Let's not jump straight away to form fields , what I would love to do is create one more template
with simpe text written. We would display that when user clicks on Create User hyperlink.
I would love to render the template and see what happens when I click on Create User Hyperlink.
Now, over here I am simply rendering the template and not doing anything else. Call this view
when url changes to /#Create. So for that we go back to the place where we have defined our
create route and its time we call the render method of specificUserView.
Run your application to check if throws any error in console. If all is fine the you should be able
to see our text being printed. Lets add our form elements ready and create our form which would
accept the required properties. When we add our input fields the form would look quiet similar
to:
delegateEvents takes the events: { ... } declaration for your view instance, and binds the specified
events to the specified DOM elements, with the specified callback methods to handle the events.
We need to have a submit button click. So we create a event for this in our
as below:
Run your application to check if throws any error in console. Click on the Save button to check if
the console message is reflecting in F12 console window.
Now, we need work on saveUserDetails method. This method is responsible to create a model
object with current filled properties and saving the details to the server.
model.save({}, {
success: function () {
console.log('Data Saved');
route.navigate('', { trigger: true });// Navigate back to listing page
}
});
Editing a user
Now, here come's the maximum challenge. We would be using our create form to display the
edit information also. For that we need to make some changes to the code.
Routing
Hide Copy Code
//When hash tag has localhost# register the below route
route.on('route:edit', function (userId) {
var _objUserEdit = new specificUserView();
_objUserEdit.render(userId);
});
Our routing would accept Id as parameter and it will be passed to the render method.
Now, we need to change our view to accept our User Id and fetch data with respect to the User
Id. Also, we need to update our view which would display value when provided. So, for that I
changed my specific user View var specificUserView as :
_userModel.fetch({
data: {id:userId},
success: function (data) {
var _userDetailTemplate = _.template($('#user-detail-template').html(),
{ user: data });
self.$el.html(_userDetailTemplate);
}
});
}
else
{
// User is created
var _userDetailTemplate = _.template($('#user-detail-template').html(),
{ user: null });
this.$el.html(_userDetailTemplate);
}
So, if you can see now all the input elements are binded with the value :
It is not esential to keep your template file like the way it has been done above, you have
alternatives like handlebar.js and more which would allow you to create template in different file.
Compile it prehand or at run time. More Details about Handlebar's.
Areas of Refactoring
The above code is very raw version of using Backbone.js. We would need refactoring on the
code mentioned above. Like when you save a user we should navigate back to the listing page to
display list of user's. e.g.
this.$el.removeData().unbind();