Reputation: 353
I'm building a simple backbone app that have 4 routes: home, about, privacy and terms. But after setting the routes I have 3 problems:
The "terms" view isn't rendering;
When I refresh the #about or the #privacy page, the home view renders after the #about/#privacy view
When I hit the back button the home view never renders. For example, if I'm in the #about page, and I hit the back button to the homepage, the about view stays in the page
I don't know what I'm doing wrong about the 1st problem. I think that the 2nd and 3rd problem are related with something missing in the home router, but I don't know what is.
Here is my code:
HTML
<section class="feed">
<script id="homeTemplate" type="text/template">
<div class="home">
</div>
</script>
<script id="termsTemplate" type="text/template">
<div class="terms">
Bla bla bla bla
</div>
</script>
<script id="privacyTemplate" type="text/template">
<div class="privacy">
Bla bla bla bla
</div>
</script>
<script id="aboutTemplate" type="text/template">
<div class="about">
Bla bla bla bla
</div>
</script>
</section>
The views
app.HomeListView = Backbone.View.extend({
el: '.feed',
initialize: function ( initialbooks ) {
this.collection = new app.BookList (initialbooks);
this.render();
},
render: function() {
this.collection.each(function( item ){
this.renderHome( item );
}, this);
},
renderHome: function ( item ) {
var bookview = new app.BookView ({
model: item
})
this.$el.append( bookview.render().el );
} });
app.BookView = Backbone.View.extend ({
tagName: 'div',
className: 'home',
template: _.template( $( '#homeTemplate' ).html()),
render: function() {
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});
app.AboutView = Backbone.View.extend({
tagName: 'div',
className: 'about',
initialize:function () {
this.render();
},
template: _.template( $( '#aboutTemplate' ).html()),
render: function () {
this.$el.html(this.template());
return this;
}
});
app.PrivacyView = Backbone.View.extend ({
tagName: 'div',
className: 'privacy',
initialize: function() {
this.render();
},
template: _.template( $('#privacyTemplate').html() ),
render: function () {
this.$el.html(this.template());
return this;
}
});
app.TermsView = Backbone.View.extend ({
tagName: 'div',
className: 'terms',
initialize: function () {
this.render();
},
template: _.template ( $( '#termsTemplate' ).html() ),
render: function () {
this.$el.html(this.template()),
return this;
}
});
And the router:
var AppRouter = Backbone.Router.extend({
routes: {
'' : 'home',
'about' : 'about',
'privacy' : 'privacy',
'terms' : 'terms'
},
home: function () {
if (!this.homeListView) {
this.homeListView = new app.HomeListView();
};
},
about: function () {
if (!this.aboutView) {
this.aboutView = new app.AboutView();
};
$('.feed').html(this.aboutView.el);
},
privacy: function () {
if (!this.privacyView) {
this.privacyView = new app.PrivacyView();
};
$('.feed').html(this.privacyView.el);
},
terms: function () {
if (!this.termsView) {
this.termsView = new app.TermsView();
};
$('.feed').html(this.termsView.el);
}
})
app.Router = new AppRouter();
Backbone.history.start();
I'm missing something but I don't know what.
Thanks
Upvotes: 3
Views: 235
Reputation: 15003
In addition to everything suggested by Rayweb_on, remove the call to render
from the initialize
methods of AboutView
, PrivacyView
and TermsView
and in your route functions, replace $('.feed').html(this.aboutView.el);
, etc. with $('.feed').html(this.aboutView.render().el);
, etc.
Also, define a variable in your router called currentView
or something like that and set it to whatever view your route functions choose. In each route function, check if it's been set and if so, call remove()
on it before rendering the new view. These changes should keep previously-rendered views from stepping on new ones and make sure that the newly-rendered view is up-to-date.
Upvotes: 2
Reputation: 3727
I think you need to move your script templates out of your .feed html element, when you render the HomeListView view it will remove everything inside its el, then the script templates will be unavailable to the other views that you are calling iside of the HomeListView.
<section class="feed">
</section>
<script id="homeTemplate" type="text/template">
<div class="home">
</div>
</script>
<script id="termsTemplate" type="text/template">
<div class="terms">
Bla bla bla bla
</div>
</script>
<script id="privacyTemplate" type="text/template">
<div class="privacy">
Bla bla bla bla
</div>
</script>
<script id="aboutTemplate" type="text/template">
<div class="about">
Bla bla bla bla
</div>
</script>
also you are missing a colon in the render function for the termsView
render: function () {
this.$el.html(this.template());
return this;
}
Upvotes: 2