我在Web应用程序中使用Ember-cli。我有一个倒计时组件,可以在UI上显示倒数计时器。这是我的组件代码。
export default Ember.Component.extend({
end_time: 0,
start_time: 0,
some_id: 0,
timer: 0, // Show this in UI - {{timer}} Seconds
init: function() {
this._super();
let end_time = this.get("end_time"), // 1479476467693
start_time = this.get("start_time"), // 1479476381491
some_id = this.get("some_id");
let wait_time = Math.floor((end_time - start_time)/1000);
this.set('timer', wait_time);
let timerName = "timer_" + some_id;
let _self = this;
window.initTimer.someTimer[timerName] = setInterval(function() {
_self.set('timer', wait_time);
if(wait_time <= 0) {
clearInterval(window.initTimer.someTimer[timerName]);
}
wait_time --;
}, 1000);
}
});
如果我将其添加到单个路由,则此组件工作正常。
现在,我已经将此组件添加到了父路由和子(/:ID)路由中,因为我需要在两个模板上都显示该组件。在子(/:ID)模板中,我有一个按钮可以清除计时器。因此,我为该按钮操作添加了此代码。
buttonAction: function(some_id) {
let timerName = "timer_" + some_id;
clearInterval(window.initTimer.someTimer[timerName]);
}
奇怪的是,当调用buttonAction时,仅清除了子模板上的计时器。父模板上的计时器保持运行。但是两个计时器都分配给一个全局变量(
window.initTimer.someTimer
),在我运行clearInterval()
时应将其清除。单击子模板上的一个按钮,是否有任何解决方案可以清除父路由和子路由上的计时器?无法弄清楚什么是Ember在玩全局变量!
最佳答案
Ember在这里没有任何魔力,但是您的代码非常复杂!
有趣的问题是some_id
的来源。如果两者都不相同,那么您要呼叫哪个人?
假设您有ID buttonAction
和one
。然后,您在two
和window.initTimer.someTimer.timer_one
处有两个间隔。现在,如果您清除window.initTimer.someTimer.timer_two
,为什么还要清除window.initTimer.someTimer.timer_one
?好吧,这不是,这就是为什么您的代码无法正常工作的原因。
假设您只有一个ID,两个计时器的呼叫为window.initTimer.someTimer.timer_two
。
然后,第二个组件的theOnlyOne
挂钩将重新分配init
,因此,当您调用window.initTimer.someTimer.timer_theOnlyOne
时,只能重置第二个组件。这就是为什么您的代码无法正常工作的原因。
那你现在应该怎么办?首先,您确实应该停止使用全局对象!在余烬生态系统中,有许多更好的方法可以做到这一点。
对于您的计时器,您应该签出ember-concurrency。
如果要使用全局状态,则应使用buttonAction
。但是,对于您的问题,我不建议这样做,因为它违反了DDAU原则。但是,要告诉您什么是正确的方法来做您想做的事情,我们需要了解为什么有这个计时器,它们之间的关系以及为什么要一键取消两个计时器。可能您会在组件外部拥有一些计时器状态,并将其传递给组件。 service
可能会有所帮助。但这确实取决于您的用例。