MVC:告诉控制器停止

发布于 2024-11-23 20:27:46 字数 1239 浏览 4 评论 0原文

我正在尝试 javascript 和 MVC 模型。我想(简化示例)在屏幕上将对象移动 1 到 10 之间的随机像素数,然后在达到 400 像素时停止。

view 设置为观察 model,它具有 notifyObservers() 函数。

当单击视图上的开始按钮时,它会向控制器发送一条startButtonClicked消息。

controller.startButtonClicked = function () {

    var animate = function () {

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

    animate();
}

这将运行 modelshift() 函数:

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, 
};

效果很好,并且对象按其应有的方式停止在 400 像素左右。然而,controller.startButtonClicked() 中的 setTimeout 循环仍然在嗡嗡作响。

[编辑:据我了解,传统的MVC模型不允许模型直接与控制器通信,因此模型不能只是告诉控制器停止计时器。]

所以,最后的问题是:如何使控制器中的循环停止?

我想到的可能的解决方案:

  • 让模型告诉视图,然后视图告诉视图控制器。但这似乎很啰嗦。
  • 让控制器询问模型是否完成。但这似乎违背了MVC结构。
  • 获取 shift() 函数以在完成时向控制器返回 false

任何使用 MVC 一段时间的人都知道正确的做法是什么吗?

谢谢!

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 tells 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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡淡の花香 2024-11-30 20:27:46

像这样的东西:

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, 
};

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, 
};
长亭外,古道边 2024-11-30 20:27:46

您需要使用 clearTimeout(arg),其中 argsetTimeout 调用的返回值。

另外,请注意 setTimeout() 的低值(< 50),您编写的代码每秒调用动画 50 次。

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, 
};

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, 
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文