I’m creating a simple Backbone app for learning purposes. I’m just creating a time and date display. The display has to update at least every minute. I’m using “Time” for the model and “TimeView” for the View. My first question is sort-of philosophical, which holds the setInterval, the Model or the View? I think that the Model should self-update but I couldn’t get the code to work. It looks like it’s updating the model but the binding of model.update() to the view.render() function doesn’t work.
In the code below, I switched the setInterval to the View and commented out my other attempt. Even though this works, (and maybe the View should control the updating of the model) but this.model.bind( ‘update’, this.render ) doesn’t work and I have to initiate the render seperately which feels wrong.
var Time = Backbone.Model.extend({
initialize: function(){
_.bindAll( this, 'update', 'startLoop', 'stopLoop' );
//this.startLoop();
this.update();
},
startLoop: function(){
this.update();
this.interval = window.setInterval(_.bind(this.update, this), 10000);
},
stopLoop: function(){
this.interval = window.clearInterval( this.interval );
},
update: function(){
var days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday' ];
var months = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ];
var date = new Date();
var tHour = date.getHours();
if( tHour < 12 ){ if( tHour == 0 ) tHour = 12 } else { tHour = tHour-12 };
tHour = tHour.toString();
var tMin = date.getMinutes();
tMin = ( tMin < 10 ) ? '0' + tMin.toString() : tMin.toString();
this.set({
hour : tHour,
ampm : ( date.getHours() < 12 ) ? "am" : "pm",
minute : tMin,
day : days[ date.getDay() ],
month : months[ date.getMonth() ],
date : date.getDate(),
year : date.getFullYear()
});
}
});
var TimeView = Backbone.View.extend({
el: '#time-date-display',
interval: 0,
template: $( '#tpl-time-date' ).html(),
initialize: function(){
_.bindAll( this, 'render' );
this.model = new Time();
this.render();
//this.model.bind( 'update', this.render );
this.interval = window.setInterval( _.bind( function(){ this.model.update(); this.render();}, this), 10000 );
},
render: function(){
//alert( 'TimeView.render()' );
$( this.el ).html(
_.template( this.template, this.model.toJSON())
);
}
});
$( 'body' ).append( _.template( $( '#tpl-time-weather-display' ).html()));
var tv=new TimeView();
You are binding to the
updateevent on the model, but that event will never be triggered. Callingupdateon the model isn’t the same as anupdateevent being generated. Instead, bind to the model’schangeevent, then the view will be updated.Regarding the philosophical question, I’d choose the model to be updating with the time, too, but this example is so contrived it’s almost arbitrary.