Is There Any Hook That Runs After The Dom Settles

I’m learning Ember JS with Foundation CSS framework but I’m having a little problem with instantiating a plugin.

I’m instantiating the javascript plugin in application.hbs like this:

...
{{outlet}}
<script>
  $(document).foundation();
</script>

I also have a component:

<div class="sticky" data-sticky data-anchor="content">
  <ul class="vertical tabs module-side-panel__list" id="module-side-panel__list" data-tabs>
    {{#each boot.modules key='type' as |module index|}}
      <li class="module-side-panel__list-item tabs-title {{if index '' 'is-active'}}">
        <a href="#{{module.module_name}}" aria-selected="{{if index '' 'true'}}">{{module.module_name}}</a>
      </li>
    {{/each}}
  </ul>
</div>

The problem is that by the time the plugin is instantiated and run, each helper has not added the li tags to the DOM causing the plugin to misbehave.

After a lot of research into the docs, I settled for the didRender hook to instantiate the plugin. I noticed didRender runs multiple times for the same component so I added code to prevent multiple instantiation. My question is, is there a better way?

Typically I run.schedule('afterRender', ...) in didInsertElement

I actually tried this before settling for didRender although I was calling scheduleOnce. I changed my code to use schedule and inserted it in the didRender and didInsertElement hooks and both worked. I think I’ll settle for the didInsertElement since although didRender is the only hook that is guaranteed to fire after the DOM has settled, it is also going to fire during updates.

Thanks for your response. It helped me.

didInsertElement is the right hook for this kind of thing.

It looks like Foundation supports initializing a specific element at a time, instead of trying to do the whole document. That makes more sense when using a client-side framework like Ember.

I would remove $(document).foundation() and just do:

didInsertElement() {
  this.$().foundation();
}

in any component that uses Foundation features.

1 Like

Hi. I am facing another issue that is rooted to knowing when the DOM has settled.

I have components something like:

{{! parent-component.hbs}}
{{child-component data=model}}
{{! child-component.hbs}}
{{#each data.attributes as |field|}}
  {{component concat(field.fieldtype "-control")}}
{{/each}}

What I am trying to achieve is to dynamically add some components to the page and that is working as expected. The only problem with my code is that after child-component is through with it’s work, parent-component is supposed to rearrange the components (grid layout stuff).

Initially, I hooked into didInsertElement to schedule into the afterRender queue. This didn’t work as the children components were not yet added to the DOM.

The solution I’m working on is to have each of the child components fire a custom event after they are rendered. I believe this can be done in the didRender hook of each of the child components. parent-component can then listen for these events and schedule into the afterRender queue.

Is this a good idea or is there something in-built that I should be doing instead?

So I discovered that this approach was correct. Some parts of the code was actually buggy. Sorry for the noise.

1 Like