在我的车把模板中:
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秒更新一次currentTime到视图?
我已阅读Ember推荐的Ember.run.later
,但我无法弄清楚将它放在何处以及如何使用此助手调用它。
答案 0 :(得分:52)
您可以像使用setTimeout
一样使用Ember.run.laterEmber.run.later((function() {
//do something in here that will run in 2 seconds
}), 2000);
我不确定内部是什么,但我知道集成测试Ember要求你使用run.later(如果你不测试代码不会等待超时完成)。
答案 1 :(得分:11)
您不希望将超时添加到帮助程序中,您需要将其添加到全局变量中,然后从中执行差异操作。你想要使用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'}}
答案 2 :(得分:6)
你想使用Embers.run循环,而不是使用setTimer。
当前(今天)版本的ember需要使用context
this
格式(更新Toran Billups答案)
this._debouncedItem = Ember.run.later(this, () => {
debugger;
}, 5000);
我强烈建议保留对later()的响应的引用,并在destroy
hook中取消它
destroy() {
this._super(...arguments);
Ember.run.cancel(this._debouncedItem);
},
答案 3 :(得分:2)
你可以使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);
}
答案 4 :(得分:1)
我有点过时的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具有单线程执行(除非您使用webworkers),这意味着它将以串行方式逐个执行。当您使用setInterval
时,它将每隔x
毫秒将您的函数排入此主执行队列。 setInterval
使用传递的time
进行排队。
Ember运行循环将计算每个运行循环中的绑定和其他重要事物,因此在循环结束时我们确定已经准备好了更改。有像Em.run.next这样的钩子,以确保这些代码在运行时将在上一次运行循环中完成更改。类似地,当你将时间传递给Em.run.later时,它也将在那么多时间后运行,并且还支持在函数内设置this
的参数。主要是在处理函数内部的某些变量或模型/控制器数据时。
在你的情况下,setInterval看起来没问题(对我而言)。