ember-time icon indicating copy to clipboard operation
ember-time copied to clipboard

Wanted to share our solution

Open gerry3 opened this issue 11 years ago • 4 comments

Thanks so much for this example. Here is what our solution looks like in coffeescript with jasmine tests. Note: we load moment onto Ember rather than window, hence Ember.moment.

from_now_view.js.coffee:

App.FromNowView = Ember.View.extend
  TICK_DELAY: 5000
  classNames: 'timestamp'
  template: Ember.Handlebars.compile('{{view.output}}')

  output: (-> Ember.moment(@get('value')).fromNow() ).property('value')

  didInsertElement: -> @tick()

  tick: -> @nextTick = Ember.run.later @, @tock, @TICK_DELAY

  tock: ->
    @notifyPropertyChange 'value'
    @tick()

  willDestroyElement: -> Ember.run.cancel @nextTick

from_now_view_spec.js.coffee:

describe 'FromNowView', ->
  model = view = null

  beforeEach ->
    model = Em.Object.create createdAt: Date.now()
    view = App.FromNowView.create valueBinding: 'model.createdAt'

  describe 'output property', ->
    it 'outputs moment fromNow', ->
      expect(view.get 'output').toBe('a few seconds ago')

  describe '#didInsertElement', ->
    it 'starts ticking', ->
      spyOn view, 'tick'
      view.didInsertElement()
      expect(view.tick).toHaveBeenCalled()

  describe '#tick', ->
    it 'tocks', ->
      spyOn Ember.run, 'later'
      view.tick()
      expect(Ember.run.later).toHaveBeenCalledWith(view, view.tock, view.TICK_DELAY)

  describe '#tock', ->
    it 'touches the value', ->
      spyOn view, 'notifyPropertyChange'
      view.tock()
      expect(view.notifyPropertyChange).toHaveBeenCalledWith('value')

    it 'ticks', ->
      spyOn view, 'tick'
      view.tock()
      expect(view.tick).toHaveBeenCalled()

  describe '#willDestroyElement', ->
    it 'stops ticking', ->
      spyOn Ember.run, 'cancel'
      view.nextTick = 'abc'
      view.willDestroyElement()
      expect(Ember.run.cancel).toHaveBeenCalledWith('abc')

gerry3 avatar Sep 25 '13 18:09 gerry3

This is awesome, and a very detailed spec. I know the Ember team favour QUnit, but I still love Jasmine for its readability.

This repo/post was written before components were introduced, but now it seems exactly the sort of thing you’d create a {{from-now}} component for.

jgwhite avatar Sep 26 '13 16:09 jgwhite

Yep, definitely will implement this as a component now. Thanks for the example!

neverfox avatar May 14 '14 05:05 neverfox

One thing I've found a need for is to be able to recalculate a computed property when certain time events occur, like when the date rolls over to the next day (because the computed property does calculations based on the current date). I think I can leverage some of this for that purpose. I can put the logic on the application controller and use needs to "inject" the current time computed where I, well, need it.

neverfox avatar May 14 '14 05:05 neverfox

@neverfox I know a few folks have implemented a clock service and injected it wherever it’s needed. It’s essentially the same as what your propose. Would love to see your implementation. It’s a pattern worth documenting.

jgwhite avatar May 14 '14 05:05 jgwhite