Horváth, Győző
senior lecturer
horvath.gyozo@inf.elte.hu
Financed from the financial support ELTE won from the Higher Education Restructuring Fund of the Hungarian Government
An extension layer over Backbone features
The following considerations about view and memory management are from the great book of Addy Osmani.
The template
<script type="text/html" id="my-view-template">
<div class="row">
<label>First Name:</label>
<span><%= firstName %></span>
</div>
<div class="row">
<label>Last Name:</label>
<span><%= lastName %></span>
</div>
<div class="row">
<label>Email:</label>
<span><%= email %></span>
</div>
</script>
The view
var MyView = Backbone.View.extend({
template: $('#my-view-template').html(),
render: function() {
// compile the Underscore.js template
var compiledTemplate = _.template(this.template);
// render the template with the model data
var data = _.clone(this.model.attributes);
var html = compiledTemplate(data);
// populate the view with the rendered html
this.$el.html(html);
}
});
Using the view
var Person = Backbone.Model.extend({
defaults: {
"firstName": "Jeremy",
"lastName": "Ashkenas",
"email": "jeremy@example.com"
}
});
var Derick = new Person({
firstName: 'Derick',
lastName: 'Bailey',
email: 'derickbailey@example.com'
});
var myView = new MyView({
model: Derick
});
myView.setElement("#content");
myView.render();
Marionette.ItemView
var MyView = Marionette.ItemView.extend({
template: '#my-view-template'
});
The view
var ZombieView = Backbone.View.extend({
template: '#my-view-template',
initialize: function() {
// bind the model change to re-render this view
this.listenTo(this.model, 'change', this.render);
},
render: function() {
// This alert is going to demonstrate a problem
alert('We`re rendering the view');
}
});
Using the view
var Derick = new Person({
firstName: 'Derick',
lastName: 'Bailey',
email: 'derick@example.com'
});
// create the first view instance
var zombieView = new ZombieView({
model: Derick
});
// create a second view instance, re-using
// the same variable name to store it
zombieView = new ZombieView({
model: Derick
});
Derick.set('email', 'derickbailey@example.com');
Reparation
var ZombieView = Backbone.View.extend({
template: '#my-view-template',
initialize: function() {
// bind the model change to re-render this view
this.listenTo(this.model, 'change', this.render);
},
close: function() {
// unbind the events that this view is listening to
this.stopListening();
},
render: function() {
// This alert is going to demonstrate a problem
alert('We`re rendering the view');
}
});
Using the repaired view
var Jeremy = new Person({
firstName: 'Jeremy',
lastName: 'Ashkenas',
email: 'jeremy@example.com'
});
// create the first view instance
var zombieView = new ZombieView({
model: Jeremy
})
zombieView.close(); // double-tap the zombie
// create a second view instance, re-using
// the same variable name to store it
zombieView = new ZombieView({
model: Jeremy
})
Jeremy.set('email', 'jeremyashkenas@example.com');
Marionette.ItemView
with automatic close()
method.
var ZombieView = Marionette.ItemView.extend({
template: '#my-view-template',
initialize: function() {
// bind the model change to re-render this view
this.listenTo(this.model, 'change', this.render);
},
render: function() {
// This alert is going to demonstrate a problem
alert('We`re rendering the view');
}
});
Rendering the view (boilerplate code)
var Joe = new Person({
firstName: 'Joe',
lastName: 'Bob',
email: 'joebob@example.com'
});
var myView = new MyView({
model: Joe
})
myView.render();
// show the view in the DOM
$('#content').html(myView.el)
Marionette.Region
// create a region instance, telling it which DOM element to manage
var myRegion = new Marionette.Region({
el: '#content'
});
// show a view in the region
var view1 = new MyView({ /* ... */ });
myRegion.show(view1);
// somewhere else in the code,
// show a different view
var view2 = new MyView({ /* ... */ });
myRegion.show(view2);
var MyView = Marionette.ItemView.extend({
template: "#some-template"
});
new MyView({
model: modelInstance
}).render();
Marionette.CollectionView.extend({
childView: MyChildView
});
show()
methodvar RootView = Mn.LayoutView.extend({
template: '#root-template'
regions: {
header: '#navbar',
content: '.content-area',
footer: 'footer'
},
initialize: function() { /* ... */ },
onBeforeShow: function() {
this.getRegion('header').show(new HeaderView());
this.getRegion('footer').show(new FooterView());
this.getRegion('content').show(new IndexView());
}
});