title: Using `afterRender` hook with nested views
body: <p><a href="http://jsfiddle.net/arasbm/vPbM4/4/" rel="nofollow noreferrer">Here is the jsFiddle if you like to see code first</a></p>
  
  <p>What I want to do is simple: execute some (actually a lot) of view layer Javascript code from jQuery and jsPlumb libraries after ALL the views in the current route have finished rendering. After getting some help from <a href="https://stackoverflow.com/a/13339048/527559">this solution</a> and finding that ember-latest has just been updated to include <code>afterRender</code> hook, I decided to upgrade. I now have the almighty <code>afterRender</code> hook. </p>
  
  <p>All the views I am inserting into the dom have a <code>block</code> class associated with them. So the way I have been testing to see if all the views are in the dom is using <code>$('.block').size()</code> and seeing if it matches expected number. </p>
  
  <p>However I am facing some issues when I try to use this hook in my application. I first tried to call the <code>afterRender</code> in the router, after the calls to <code>connectOutlets</code>. I always get only 1 block when I print out the number of blocks in dom while there should be 10.</p>
  
  <p>If I put this code in <code>didInsertElement</code> of my local <code>block</code> view:</p>
  
  <pre><code>didInsertElement: () -&gt;
      knob = this.$("##{@get 'knobId'}")
      name = this.$(".name")
      main = this.$(".main") #block html content will be injected into main
      knob.hide()
  
      Ember.run.scheduleOnce('afterRender', this, ()-&gt;
        console.log "&gt;&gt; block count: ", $(".block").size()
      )
      ...
  </code></pre>
  
  <p>Then I get the following output:</p>
  
  <pre><code>&gt;&gt; block count: 1
  &gt;&gt; block count: 10
  &gt;&gt; block count: 10
  &gt;&gt; block count: 10
  &gt;&gt; block count: 10
  &gt;&gt; block count: 10
  &gt;&gt; block count: 10
  &gt;&gt; block count: 10
  &gt;&gt; block count: 10
  &gt;&gt; block count: 10
  </code></pre>
  
  <p>For some reason the first iteration I only get 1 <em>block</em> in the dom and after that I get all 10. I am not sure why. But the main issue here is that if I put the hook inside <code>didInsertElement</code>, the code gets executed for an arbitrary number of views depending on data (in this example 10). However I only want to run this code once after all views have finished rendering. </p>
  
  <p>Note that the view I am working with has nested data. I tried to <a href="http://jsfiddle.net/arasbm/vPbM4/4/" rel="nofollow noreferrer">reproduce this on jsFiddle,</a> but I failed in the sense that it seems to work all find and dandy on the fiddle. Maybe because my views are big and complex it is causing some synchronization issues? In any event, I think we can use the fiddle as a way to discuss a solution and I can test it locally. </p>
  
  <p>One hack I tried to do to get around the issue is to schedule my code to run after 500ms delay using <code>Ember.run.later</code>. That did solve the issue on my local machine. However, using a timer to do this is very sheep dung and does not work reliably since different browsers or machines may take longer to render the views.</p>
  
  <p>This is a though one to reproduce and I have already spent much time trying to find a solution. I would appreciate any help in reproducing the problem here or finding a solution.</p>
  
  <p><strong>Edit (workaround):</strong> Thanks to look for helping me troubleshoot this problem, and by looking at <a href="https://stackoverflow.com/a/12097401/527559">this post about a similar problem</a>, I came up with the following temporary workaround, which I put inside the router code:</p>
  
  <pre><code>    # Keep trying until there are two or more blocks in DOM
      blocksLoaded = -&gt;
        console.log "blocks number ...: ", $('.block').size()
        if $('.block').size() &gt; 1
          console.log "Yay!...we have ", $('.block').size()
          startTraversingBlocks()
        else
          Ember.run.next(this, ()-&gt;
            blocksLoaded()
          )
  
      blocksLoaded()
  </code></pre>
  
  <p>This outputs:</p>
  
  <pre><code>blockies number ...: 0
  blockies number ...: 1
  blockies number ...: 1
  blockies number ...: 1
  ...
  blockies number ...: 1
  blockies number ...: 10
  Yay!...we have 10
  </code></pre>
  
  <p>As Luke pointed out, the problem here is that my nested views are being rendered over several RunLoops. when I refresh the browser I get a different number of <code>blockies number ...: 1</code> output everytime, anywhere between 4 and 10 times during my tests.</p>
  
  <p>In my opinion this is not a very good solution, but it seems to work for my use case. I feel that there is a need here for another hook that allows one to access DOM when it is guaranteed all the elements from views are accessible through jQuery selectors, but perhaps I am missing something here.</p>