开发者

MVC: Telling the controller to stop

I'm experimenting with javascript and MVC models. I want to (simplified example) move an object across the screen a random number of pixels between 1 and 10 and then have it stop when it gets to, say, 400 pixels.

The view is set up to observe the model, which has a notifyObservers() function.

When the start button on the view is clicked it sends a startButtonClicked message to the controller.

controller.startButtonClicked = function () {

    var animate = function () {

        controller.getModel().shift();  // get the model and run the shift() function
        setTimeout(animate, 20);
    };

    animate();
}

This runs the model's shift() function:

model.shift = function () {

    if(model.x < 400) {
        model.x += Math.floor(Math.random()*11);  // Add up to 10 pixels
    }

    model.notifyObservers();  // Tells view to update, 
};

This works fine, and the object stops at around 400 pixels as it should. However, the setTimeout loop in controller.startButtonClicked() is still whirring away.

[Edit: As I understand it, the traditional MVC model doesn't allow the model to communicate with the controller directly, so the model can't just tell the controller to stop the timer.]

So, finally to the question: How do I make the loop in the controller stop?

The possible solutions I've thought of:

  • Get the model to tell the view, which then t开发者_如何学Goells the controller. But that seems very long-winded.
  • Get the controller to ask the model if it's done. But that seems to go against the MVC structure.
  • Get the shift() function to return false to the controller when it's done.

Anyone who's been doing MVC for a while know what the right way of doing it would be?

Thanks!


Something like this:

var t;  // feel free to make this a non global variable
controller.startButtonClicked = function () {

    var animate = function () {

        controller.getModel().shift();  // get the model and run the shift() function
        t = setTimeout(animate, 20);
    };

    animate();
}


model.shift = function () {

    if(model.x < 400) {
        model.x += Math.floor(Math.random()*11);  // Add up to 10 pixels
    }
    else { 
        clearTimeout(t);
    }

    model.notifyObservers();  // Tells view to update, 
};


You need to use clearTimeout(arg) where arg is the return value from a setTimeout call.

Also, be careful with low (< 50) values for setTimeout(), what you have coded calls animate 50 times per second.

controller.startButtonClicked = function () {

  var animate = function () {

    var m = controller.getModel();
    m.shift(controller);  // get the model and run the shift() 
    m.timerInterval = setTimeout(animate, 20);
  };

  animate();
}

model.shift = function () {

   if(model.x < 400) {
      model.x += Math.floor(Math.random()*11);  // Add up to 10 pixels
   }
   else if (model.timerInterval)
   {
     clearTimeout(model.timerInterval);
   }
   model.notifyObservers();  // Tells view to update, 
};
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜