tellob
tellob

Reputation: 1250

Backbone.js Timer - useless setInterval call

Although I searched for a solution, i did not found one for my problem. Im using cordova and jquery mobile. there are fired to events: document.ready and the device ready of cordova. i want to check the loading states by checking to booleans, to know when to start the main application.

so have a look at my code:

First: The first js-File loaded:

function checkReadyStates() {
    if(domReady && cordovaReady) {
        timer.stop();
        start();
    }
}

var domReady = false;
var cordovaReady = true;
var timer = new TimerModel({interval : 50, method : checkReadyStates});
timer.start();

// get notified when DOM is loaded
$(document).ready(function() {
    ConsoleController.info('Document ready.');
    domReady = true;
});

// get notified when cordova is ready
document.addEventListener('deviceready', function() {
    ConsoleController.info('Cordova loaded.');
    cordovaReady = true;
}, false);

Second: The TimerModel:

define(['backbone'],function(Backbone) {

var model = Backbone.Model.extend({

    defaults: {
        timerObject : null,
        active : false,
        interval : 1000,
        method : null,
    },

    // init timer
    initialize : function() {
        _.bindAll(this, 'start', 'stop'); // context bindings
    },

    // starts the timer with given interval
    start : function() {
        if(!this.active) {
            this.active = true;
            this.timerObject = setInterval(this.method, this.interval);
        }
    },

    // stops timer
    stop : function() {
        this.active = false;
        clearInterval(this.timerObject);
    }

});

// return the timer model
return model;

});

Hope someone's able to help. Thanks!

Upvotes: 2

Views: 2734

Answers (1)

jevakallio
jevakallio

Reputation: 35940

On this line of code here

this.timerObject = setInterval(this.method, this.interval);

Both this.method and this.interval are undefined, so you're setting nothing running never. The reason for this is that Backbone.Model doesn't define the properties passed in the constructor on the instance itself, but in an internal property called attributes. You can access the attributes using the model.get(property) method:

this.timerObject = setInterval(this.get('method'), this.get('interval'));

Furthermore it doesn't really make sense to define the timer as a model. No doubt you'll get it to work, but it's not what Backbone.Modelis intended for. Models are used to represent a piece of data, not functionality. I think a simple function would serve you better here.

Edit: To rephrase, models are not just for data, but they should contain data. The model is a good place to define functions (methods) that operate on that data. Your TimerModel on the other hand is pure logic - it doesn't represent or encapsulate any data or state. I feel that logic is better encapsulated as a simple function "class":

var Timer = function(options) {
    options = options || {};
    this.active = false;
    this.interval = options.interval || 1000;
    this.method = options.method || null;


    // starts the timer with given interval
    this.start = function() {
        if(!this.active) {
            this.active = true;
            this.timerObject = setInterval(this.method, this.interval);
        }
    };

    // stops timer
    this.stop = function() {
        this.active = false;
        clearInterval(this.timerObject);
    };

    _.bindAll(this, 'start', 'stop')
});

Usage:

var timer = new Timer({interval: 50, method:checkReadyStates});

Upvotes: 3

Related Questions