【问题标题】:SetTimeout inside emberjs modelemberjs模型中的SetTimeout
【发布时间】:2023-03-11 07:34:01
【问题描述】:

我的 emberjs 应用程序中有一个没有任何数据库数据的模型。我创建了这个模型,因为我想要一些对象来汇集来自服务器的一些请求,但不绑定到控制器或视图。

类似:StatusChecker

在我的 Application.create 中,我这样做:

Webapp = Ember.Application.create({
  rootElement: '#content',
  LOG_TRANSITIONS: true,

  ready: function() {
    return Webapp.status_helper = Webapp.StatusHelper.create({
      timer: 15
    });
  }
});

这将实例化一个Webapp.StatusHelper 对象,该对象对于应用程序来说必须是唯一的。当我在这个对象上调用init 时,我也会使用默认计时器开始轮询:

Webapp.StatusHelper = Ember.Object.extend({
  init: function(params) {
    this.timer = this.get("timer");
    this.timeoutID = null;
    this.controller = null;
    this.start();
  },
  start: function() {
    this.execute();
  },
  stop: function() {
    clearTimeout(this.timeoutID);
  },
  setTimer: function(newTime) {
    this.stop();
    this.timer = newTime;
    this.start();
  },
  execute: function() {
    var $this = this;
    this.stop();
    $.get("/status").done(function(data) {
      console.log(data);

      if (data["status"] === 0) { // Continue trying
        $this.timeoutID = setTimeout(function() {
          $this.execute();
        }, $this.timer * 1000);
      } else if (data["status"] === 1) { // Go to a given controller
        $this.setTimer(15);
        $this.transitionToRoute('index'); // This doesn't work
      } else {
        $this.setTimer(15);
        $this.transitionToRoute('problem'); // This doesn't work
      }
    });
  }
});

第一个问题是我无法使用此模型更改路线:$this.transitionToRoute('problem');。有没有办法从模型中做到这一点?

第二个问题是,有时当我进入控制器时,我需要在我需要停止该计时器并以另一个间隔启动它之后立即指定 StatusHelper 的间隔,如下所示:

Webapp.IndexRoute = Ember.Route.extend
  setupController: (controller) ->
    Webapp.status_helper.setTimer 15

Webapp.ProblemRoute = Ember.Route.extend
  setupController: (controller) ->
    Webapp.status_helper.setTimer 1

发生这种情况是因为我需要检查问题是否每秒钟都得到解决,并且索引页面会在需要时转换到问题页面。过渡后,我会得到 2 个,有时甚至更多的间隔来从事同一项工作。

我怎样才能停止它并只使一个功能起作用?

P.S.:如果你发现我需要用别的东西改变模型,我可以改变它。


tl;博士
  • 如何从控制器内部更改路由?
  • 我怎样才能让一个函数按间隔运行?
  • 还有其他(更好的)方法吗?


编辑

我的库的版本:

DEBUG: Ember.VERSION : 1.0.0-rc.1 ember.js:348
DEBUG: Handlebars.VERSION : 1.0.0-rc.3 ember.js:348
DEBUG: jQuery.VERSION : 1.9.1 

【问题讨论】:

    标签: javascript ember.js setinterval


    【解决方案1】:

    第一个问题是我无法使用以下方法更改模型中的路线:$this.transitionToRoute('problem');。有没有办法从模型中做到这一点?

    您不能/不应该从模型访问路由器。每当您发现有必要这样做时,就会提示您编写的代码可能不应该是模型。在这种情况下,Webapp.StatusHelper a 应该是一个控制器。所以像:

    Webapp.StatusController = Ember.Controller.extend({
      //your code here
    });
    

    然后您可以摆脱 init() App.ready() 钩子,而是使用 ApplicationRoute 的 setupController 钩子来配置和启动计时器。当然,由于您现在处于控制器中,因此您将能够访问路由器。

    我怎样才能停止它并只使一个功能起作用?

    所以基本上你需要在过渡到新路线时启动/停止计时器。使用路由的activatedeactivatesetupController 挂钩在路由更改时打开/关闭计时器。这样,您可以确保计时器仅在您需要时运行。

    Webapp.IndexRoute = Ember.Route.extend
      activate: (controller) ->
        this.controllerFor('status').setTimer 15
        this.controllerFor('status').start()
    
      deactivate: (controller) ->
        this.controllerFor('status').stop()
    
    Webapp.IndexRoute = Ember.Route.extend
      activate: (controller) ->
        this.controllerFor('status').setTimer 1
        this.controllerFor('status').start()
    
      deactivate: (controller) ->
        this.controllerFor('status').stop()
    

    【讨论】:

    • 我对这种方法的问题(Webapp.StatusHelper 作为控制器)是我们不能让 2 个控制器呈现一个页面/视图。把它想象成一个电子邮件页面,我们有 2 个页面:所有电子邮件和一封电子邮件。在他们两个中,我都想检查新电子邮件,其中一个我希望每 5 秒一次,而另一个我希望每 25 秒一次。这就是我想要的
    • OK 你想要的完全有道理,但在我看来 Webapp.StatusController 支持这一点。 “我们不能让 2 个控制器渲染一个页面/视图”是什么意思? Ember 容器将确保只有一个 Webapp.StatusHelper 实例。然后你的路由 setupController 钩子会做类似controllerFor('status').start(5) 的事情,而 deactivate 钩子会有controllerFor('status').stop()。用代码更新我的答案...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 2017-12-10
    • 1970-01-01
    相关资源
    最近更新 更多