7

This question demonstrates that overriding an Ember.View instance's didInsertElement allows you to execute some code after the view's element is in the DOM.

http://jsfiddle.net/gvUux/2/

Naturally, overriding didInsertElement on the child view class you add to an Ember.CollectionView will run the hook after each child view is rendered and inserted.

http://jsfiddle.net/BFUvK/1/

Two collection-oriented hooks on Ember.CollectionView, arrayDidChange and contentDidChange, execute after the underlying content has changed, but they execute before any rendering takes place. arrayDidChange is executed for every element added to the array, and contentDidChange wraps the content binding.

I would like to be able to hook around the rendering pipeline, something like willInsertCollection and didInsertCollection, to manipulate the DOM before and after all child elements are rendered - essentially, before and after filters around contentBinding.

Any ideas? I'm stumped.

Community
  • 1
  • 1
scottburton11
  • 251
  • 4
  • 12

2 Answers2

3

If you want to want to do something before and/or after a view has been rendered you should use willInsertElement and/or didInsertElement respectively. In this case, since you want "to manipulate the DOM before and after all child elements are rendered" you should call those on your CollectionView.

I'm not quite sure what you mean by "before and after filters around contentBinding", so if this doesn't answer your question if you could clarify I'd be happy to help.

jsFiddle if needed

Roy Daniels
  • 6,309
  • 2
  • 27
  • 29
  • 1
    Many thanks for your help. I'm afraid, though, that the CollectionView `didInsertElement` hook is fired _before_ each added child's version of `didInsertElement`, [here's a modified example.](http://jsfiddle.net/NFDqW/5/) I think I can find a workaround, but I'm still trying to find the right pattern for collections that gives me what I'm looking for. Thanks again. – scottburton11 Feb 14 '12 at 07:01
  • That modification you made is in the CollectionView's ItemView and yes that will fire before each added child's version. Can you be more specific about what exactly you're trying to accomplish? – Roy Daniels Feb 14 '12 at 12:11
  • I've update the [jsFiddle](http://jsfiddle.net/ud3323/NFDqW/) to do exactly what you were trying to do just within the CollectionView instead of the ItemView. – Roy Daniels Feb 14 '12 at 12:32
  • Thanks, I see it working now in jsFiddle. I have an exact copy of this behavior in an application, though, and it has the opposite behavior - the collectionView's `didInsertElement` fires when IT is added to the DOM, not when any child elements are added. I can't say I know why. In any case, I'll mark this as accepted. I thank you for your help! – scottburton11 Feb 14 '12 at 23:21
  • I've updated that fiddle again. Sounds like you need to manipulate the runloop here (still curious what exactly you're trying to do). The runloop is an interesting beast... I won't go too much into how it works here, but hopefully the code explains enough. Also, take a look at the [runloop's source](https://github.com/emberjs/ember.js/blob/master/packages/ember-metal/lib/run_loop.js), specifically the Ember.run.* functions. – Roy Daniels Feb 15 '12 at 01:58
0

I wanted to apply a scroll animation to slide a list up after pushing new objects. The list was rendered using an ArrayController and the #each helper. Simply triggering an event on the controller which the view subscribed to after pushing objects was causing the animation to execute before the changes to the content were actually rendered. The following technique worked perfectly for me.

//excerpt from my loadMore method on the ArrayController

var self = this;
self.content.pushObjects(moreItems);
Ember.run.scheduleOnce('afterRender', this, function()
{
  self.trigger('loadMoreComplete');
});
Aaron Storck
  • 886
  • 7
  • 16