SetTimeout против Ember.run.later в приложении ember?
Внутри моего шаблона ручек:
Today date: {{currentDate}}
Current Time: {{currentTime}}
Внутри моих помощников:
Ember.Handlebars.registerBoundHelper 'currentDate', (option) ->
moment().format('LL');
Ember.Handlebars.registerBoundHelper 'currentTime', (option) ->
moment().format('h:mm:ss a');
Как я могу обновить currentTime до представления каждые 1 секунду?
Я читал, что Ember рекомендует Ember.run.later
, но я не могу понять, куда его поместить и как его называть этот помощник.
Ответы
Ответ 1
Вы можете использовать ember.run.later, как обычно, вы используете setTimeout
Ember.run.later((function() {
//do something in here that will run in 2 seconds
}), 2000);
Я не изнутри, но я знаю, что для интеграционного тестирования ember требуется использовать run.later(если тестовый код не будет ждать окончания таймаута)
Ответ 2
Вы не захотите добавить тайм-аут в помощник, вы хотите добавить его в глобальную переменную и просто выполнить diff от него. Причина, по которой вы захотите использовать Em.run.later
, - это ввести ее в цикл выполнения (часть того, что получал Торан). Это действительно важно для тестирования.
Добавьте время к глобальной переменной
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
Ответ 3
вы хотите использовать цикл 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);
},
Ответ 4
Вы можете сделать 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);
}
Ответ 5
Я немного устарел. Пользователь 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 имеет однопоточное выполнение (если вы не используете веб-мастеров), что означает, что он будет делать вещи один за другим в последовательном порядке. Когда вы используете setInterval
, он будет запускать вашу функцию каждые x
миллисекунды в эту основную очередь выполнения. setInterval
использует пройденный time
для выполнения своей очереди.
Циклы запуска Ember будут сортировать привязки и другие тяжелые вещи в каждом цикле цикла, поэтому в конце цикла мы уверены, что изменения уже готовы. Есть крючки, такие как Em.run.next, чтобы убедиться, что эти коды при запуске будут иметь полные изменения, выполненные в последнем цикле выполнения. Аналогично, когда вы передаете время Em.run.later, он также будет работать после этого много времени, а также поддерживает параметр для установки this
внутри функции. В основном, имея дело с некоторыми переменными или данными Model/Controller внутри функции.
В вашем случае setInterval выглядит нормально (для меня).
http://jsfiddle.net/NQKvy/604/