Aaron Renoir
Aaron Renoir

Reputation: 4391

Ember.CollectionView all children didInsertElement callback

From a Ember.CollectionView is there a easy way to call a function after all childView elements have been rendered?

Something like like didInsertElement for all children.

This is what I am doing now. Is there a better way?

App.CollectionView = Ember.CollectionView.extend

  didInsertChildElements: ( ->
    if @get('childViews').everyProperty('state', 'inDOM')
     @dosomething()
  ).observes('childViews')

  itemViewClass: Ember.View.extend()

EDIT here is a better example of what I am trying to do.

For every ChildView I am setting the position using didInsertElement, then from the parent I want to scroll to a specified child using the parents didInsertElement callback. The problem is the parent's didInsertElement callback gets called before the child's.

App.CollectionView = Ember.CollectionView.extend
  dateBinding: 'controller.date'

  didInsertElement: ->
    #@scrollTo @get('date')#old way
    Ember.run.scheduleOnce('afterRender', @, 'scrollToDate')

  scrollToDate: ->
    @scrollTo @get('date')

  scrollTo: (date) ->
    day = @get('childViews').findProperty('date', date)
    pos = day.get('position')
    #console.log pos
    @$().scrollTop(pos)

  itemViewClass: Ember.View.extend
    templateName: 'home/day'
    dateBinding: 'content.date'
    position: null

    didInsertElement: ->
      @set 'position', @$().offset().top
      #console.log @get('position')

EDIT

Scheduling a afterRender callback works! Ember.run.scheduleOnce('afterRender', @, 'scrollToDate')

Upvotes: 2

Views: 1189

Answers (1)

Christopher Swasey
Christopher Swasey

Reputation: 10562

There are two ways, per ContainerView, that child views get into the dom: either they are inserted along with the parent view itself when the parent view render()s, in which case they will be in the DOM when didInsertElement is called for the parentView, or they get forced into the DOM as a consequence of childViewsDidChange adding a callback to the 'render' queue.

What you might do then is add your own callback to the afterRender queue, when [] changes (the view itself acts as the array here, for observation purposes), by which point any not 'inDOM' views will have been inserted into the view.

didInsertChildElements: ( ->
    if @get('state') === 'inDom'
        Ember.run.scheduleOnce('afterRender', this, 'dosomething');
).observes('[]')

Upvotes: 5

Related Questions