In this article we will learn about multiple views. We will understand how a view manages the updates or the events in another view. In this tutorial we will create a record list and when we click on any record from the list then that record will be displayed in the textboxes, we can edit this record and again save it in the list.
Here we will crate a list of animal records. When a user wants to select a record then the user clicks on the record then the record will be displayed automatically in the textboxes. And the user can easily update records.
The major concept to understand about this is that the child animal view is not familiar with the detailed view. Not any of the views are familiar with the other. This is important to understand about because it decouples the views. This is allows deletion of the view without updating the other views.
Now let's see how to create this application.
<html>
<head>
<title></title>
<script src="js/jquery-1.8.3.js" type="text/javascript"></script>
<script src="js/underscore.js" type="text/javascript"></script>
<script src="js/backbone.js" type="text/javascript"></script>
<style>
div .table {
display: table;
border: #ff0000 solid 1px;
padding: 5px;
}
div .tableRow {
display: table-row;
}
div .tableCell {
display: table-cell;
border: #737373 solid 1px;
padding: 5px;
}
</style>
</head>
<body>
<div id="main" class="table"></div>
<script type="text/template" id="template-animalItem">
<div id="name" class="tableCell"><%=name%></div>
<div id="color" class="tableCell"><%=color%></div>
</script>
<div id="mainedit">
Name <input type="text" id="animalname" />
Animal Color <input type="text" id="animalcolor" />
<input type="button" id="butChange" value="Update Data" />
</div>
<script type="text/javascript">
var PubSub = function () {
this.events = _.extend({}, Backbone.Events);
};
var pubSub = new PubSub();
//Create AnimalListView and loop through animals
var Animal = Backbone.Model.extend({});
var Animals = Backbone.Collection.extend({
model: Animal
});
var AnimalListView = Backbone.View.extend({
type: "AnimalListView", //for debugging
el: "#main", //the view should be decoupled from the DOM, but for this example this will do.
//collection: This will be passed at the time of initialization
initialize: function () {
},
render: function () {
_.each(this.collection.models, this.processAnimal, this);
return this;
},
processAnimal: function (animal) {
var childAnimalItemView = new AnimalItemView({ model: animal });
childAnimalItemView.render();
this.$el.append(childAnimalItemView.el);
}
});
var AnimalItemView = Backbone.View.extend({
type: "AnimalItemView", //for debugging
template: _.template($("#template-animalItem").html()),
tagName: "div",
className: "tableRow",
initialize: function () {
this.model.on("change", this.modelChanged, this);
},
events: {
"click": "viewClicked"
},
render: function () {
var outputHtml = this.template(this.model.toJSON());
this.$el.html(outputHtml);
return this;
},
modelChanged: function (model, changes) {
console.log("modelChanged:" + model.get("name"));
this.render();
},
viewClicked: function (event) {
console.log("viewClicked: " + this.model.get("name"));
pubSub.events.trigger("animal:selected", this.model);
}
});
var AnimalDetailView = Backbone.View.extend({
el: "#mainedit",
initialize: function () {
pubSub.events.on("animal:selected", this.animalSelected, this);
},
events: {
"click #butChange": "viewChanged"
},
render: function () {
var name = this.model.get("name");
this.$el.find("#animalname").val(name);
var color = this.model.get("color");
this.$el.find("#animalcolor").val(color);
},
animalSelected: function (animal) {
console.log(animal);
this.model = animal;
this.render();
},
viewChanged: function () {
var name = this.$el.find("#animalname").val();
this.model.set({ "name": name });
var color = this.$el.find("#animalcolor").val();
this.model.set({ "color": color });
}
});
var myAnimals = [
{ "id": "1", "name": "Lion", "color": "Brown" },
{ "id": "2", "name": "Tiger", "color": "Brown" },
{ "id": "3", "name": "Elephant", "color": "Black" },
{ "id": "4", "name": "Dog", "color": "White"},
{ "id": "5", "name": "Rabbit", "color": "white" }
];
var animals = new Animals(myAnimals);
var animalListView = new AnimalListView({ collection: animals });
animalListView.render();
var animalDetailView = new AnimalDetailView();
</script>
</body>
</html>
This HTML code is monitored by the View. Here the user can update the name and color of the animals. There is nothing special, there is only a display of two textboxes and a single button. These input controls are put inside the <div> that has the id "main". It allows the user to use the backbone.js view to monitor the elements and its children.
There is a variable "PubSub", referenced many times in the various views. This describes how the various views communicate with each other.