Last active
August 29, 2015 14:07
-
-
Save huafu/d62cefaf0f8d412c8fe3 to your computer and use it in GitHub Desktop.
A mixin to have a property updated each time a new `tickStep` `tickUnit` is passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
var DAYS_IN_YEAR = 365.25; | |
var DAYS_IN_MONTH = DAYS_IN_YEAR / 12; | |
var MILLISECONDS_IN = { | |
millisecond: 1, | |
second: 1000, | |
minute: 1000 * 60, | |
hour: 1000 * 60 * 60, | |
day: 1000 * 60 * 60 * 24, | |
week: 1000 * 60 * 60 * 24 * 7, | |
month: 1000 * 60 * 60 * 24 * DAYS_IN_MONTH, | |
year: 1000 * 60 * 60 * 24 * DAYS_IN_YEAR | |
}; | |
function parseUnit(unit) { | |
var res = (/s$/i.test(unit) ? unit.substr(0, -1) : unit).toLowerCase(); | |
if (!MILLISECONDS_IN[res]) { | |
throw new ReferenceError('Invalid unit `' + unit + '`'); | |
} | |
return res; | |
} | |
function toMilliseconds(value, unit) { | |
return value * MILLISECONDS_IN[parseUnit(unit)]; | |
} | |
export default Ember.Mixin.create({ | |
tickStep: 1, | |
tickUnit: Ember.required(), | |
tickProperty: Ember.required(), | |
_initWithClock: function () { | |
var meta = this._withClock = { | |
property: this.get('tickProperty'), | |
step: toMilliseconds(this.get('tickStep'), this.get('tickUnit')), | |
current: function () { | |
return Math.floor(Date.now() / this.step) * this.step; | |
}, | |
check: function (obj) { | |
if (!obj || obj.isDestroying || obj.isDestroyed) { | |
this.cancel(); | |
return; | |
} | |
var c = this.current(); | |
if (this.last !== c) { | |
this.last = c; | |
Ember.run.next(this, function () { | |
obj.set(this.property, c); | |
this.schedule(obj); | |
}); | |
} | |
else { | |
this.schedule(obj); | |
} | |
}, | |
schedule: function (obj) { | |
var self = this; | |
this.cancel(); | |
this._tiemr = setTimeout(function () { | |
self._timer = null; | |
self.check(obj); | |
}, this.step / 3); | |
}, | |
cancel: function () { | |
if (this._timer) { | |
clearTimeout(this._timer); | |
this._timer = null; | |
} | |
} | |
}; | |
meta.check(this); | |
}.on('init'), | |
_destroyWithClock: function () { | |
if (this._withClock) { | |
this._withClock.cancel(); | |
delete this._withClock; | |
} | |
}.on('destroy') | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Ember from 'ember'; | |
import WithClockMixin from 'app/mixins/with-clock'; | |
export default Ember.Controller.extend(WithClockMixin, { | |
tickStep: 5, | |
tickUnit: 'minute', | |
tickProperty: 'time', | |
time: null, | |
currentDateUpdateEvery5Minutes: function () { | |
return new Date(this.get('time')); | |
}.property('time').readOnly() | |
}); | |
/* | |
The `currentDateUpdateEvery5Minutes` property will be updated every 5 minutes, | |
to a number of milliseconds floored depending on the tickUnit and tickStep, so | |
here it'll be always a multiple of 5 minutes, so it can't be a time like '10:22', | |
it'll be instead here '10:20'. | |
It'll check for new value 3 times per step, updating only if it needs to be updated. | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment