settimeout vs. ember.run. -later在ember应用中



在我的车把模板中:

Today's date: {{currentDate}}
Current Time: {{currentTime}}

在我的助手中:

Ember.Handlebars.registerBoundHelper 'currentDate', (option) ->
  moment().format('LL');
Ember.Handlebars.registerBoundHelper 'currentTime', (option) ->
  moment().format('h:mm:ss a');

我将如何每1秒更新当前时间?

我已经阅读了Ember建议Ember.run.later,但我无法完全弄清楚它的位置以及如何使用此助手来称呼它。

您可以像通常使用settimeout

一样使用ember.run。
Ember.run.later((function() {
  //do something in here that will run in 2 seconds
}), 2000);

我不确定内部设备,但我知道集成测试Ember需要您使用Run.Later(如果不使用测试代码,则不会等待超时完成)。

您不想将超时添加到助手中,您需要将其添加到全局变量中,而与之相比。您要使用Em.run.later的原因是将其注入运行环(Toran所获得的部分)。这对于测试真的很重要。

将时间添加到全局变量

App.ApplicationRoute = Em.Route.extend({
  setupController: function(controller, model){
    this._super(controller, model);
    this.startWatchingTime(controller);
  },
  startWatchingTime: function(controller){
    var self = this;
    controller.set('currentTime', moment());
    Em.run.later(function(){
      self.startWatchingTime(controller);
    }, 1000);
  }
});

将其添加到助手

Ember.Handlebars.helper('time-diff', function(date1, date2, format, options) {
  return date1.diff(date2, format);
});

将其发送到助手

{{time-diff  controllers.application.currentTime anotherTime 'seconds'}}

http://emberjs.jsbin.com/ucuriqa/1/edit

您想使用embers.run循环而不是与settimer一起出去。

Ember的当前(今日)版本需要使用context this(更新Toran Billups答案)

this._debouncedItem = Ember.run.later(this, () => {
   debugger;
}, 5000);

我强烈建议您参考以后的响应(),并在destroy Hook

中取消它
destroy() {
   this._super(...arguments);
   Ember.run.cancel(this._debouncedItem);
},

您可以使currentDate成为常规属性

currentDate: null,
currentTime: null

您可以在控制器的构造函数中启动此计时器。

init: function () { 
  this.updateTimeProperty();
},
updateTimeProperty: function () {
  var _this = this;
  Ember.run.later(this, function() {
    _this.currentDate = moment().format('LL');
    _this.set('currentTime',  moment().format('h:mm:ss a');
    _this.updateTimeProperty());
  }, 1000);
}

我有点过时的ember用户,但是我会这样做,希望有一个更好的解决方案。

App.CurrentTimeView = Ember.View.extend({
    template : Ember.Handlebars.compile("<span>{{view.currentTime}}</span>"),
    currentTime : null,
    init : function(){
        var view = this;
        view.set('currentTime', moment().format('h:mm:ss a'));
        setInterval((function(view){
            return function(){view.set('currentTime', moment().format('h:mm:ss a'));};
        })(view),1000);
    }
});

,在模板中

{{view "App.CurrentTimeView"}}

回答您的问题,JavaScript具有单个线程执行(除非您使用Webworker),这意味着它将以串行方式进行一一做事。当您使用setInterval时,每个x毫秒都会将您的功能纳入此主要执行队列。setInterval使用传递的time进行排队。Ember Run循环将计算每个运行循环中的绑定和其他重物,因此在循环结束时,我们确定已经准备就绪更改。有像em.run.next这样的挂钩来确保运行时的这些代码将在最后一个运行循环中完成完整的更改。同样,当您将时间传递给em.run.later时,它也将在这段时间之后运行,还支持一个参数以在函数内设置this。通常,当处理功能内的某些变量或模型/控制器数据时。

在您的情况下,setInterval看起来还可以(对我来说)。

http://jsfiddle.net/nqkvy/604/

最新更新