Aakanksha
Aakanksha

Reputation: 976

Ember JS- Apply jQuery after a component is entirely rendered

I'm a beginner in ember and trying to implement a jQuery block to display my objects one after the other with a delay of 0.5 seconds.

My current code to display my ember objects is something like below

{{#if isBusy}}
  <div>Loading..</div>
{{else}}
  {{#if areLeads}}
    {{#each lead in leads}}
      <div>lead.title</div>
    {{/each}}
  {{else}}
    <div>No Leads</div>
  {{/unless}}
{{/if}}

Now, what I want exactly is that after the leads are ready to be displayed, my code should execute, as in when isBusy is false.

The following is something that I've tried

_animateLeads: ->
    alert()

didInsertElement: ->
   Ember.run.scheduleOnce 'afterRender', @, => @_animateLeads()

However, the alert pop-ups as soon as the page starts to load. I'm not much aware of the ember concepts and learning the same.

Please guide me as to how to proceed and let me know if I should provide other details. Any help is appreciated. Thanks

Update

I ended up withe the following code

 _animateLeads: Ember.observer 'leads', ->
     if @get('leads')
         $('li.leads-list-lead').each (i) ->
           $(this).fadeOut(1000).delay(2000*i).fadeIn(2000);
           return

 _animateOnInsert: (->
   Ember.run.scheduleOnce('afterRender', @, @_animateLeads)
 ).on('didInsertElement')

but the following works only when changes to the leads is made. Initially, when the page is loaded, the leads do not appear as expected i,e. in the animated way. The following also works, but again, only when the leads is changed

_animateLeads: (->
    if @get('leads')
      $('li.leads-list-lead').each (i) ->
        $(this).fadeOut(1000).delay(2000*i).fadeIn(2000);
).observes('leads')

Solution

I ended up up the following code by mixing what i was doing above that works for me.

  _animateLeads: (->
    Ember.run.scheduleOnce('afterRender', @, @_animateActiveLeads)
  ).observes('leads')

  _animateActiveLeads: (->
   if @get('leads') && @get('leadDisplay') == 'active'
     $('li.is-online').each (i) ->
       $(this).fadeOut(0).delay(1000*i).fadeIn(1850);
  )

A similar question is asked as well here that did not come up in my searches earlier. The accepted answer worked for me.

Upvotes: 0

Views: 142

Answers (2)

acorncom
acorncom

Reputation: 5955

The component hook you are probably looking for is afterRender, which will give you access to the DOM after it has rendered. If you load all your div elements as hidden and then use jQuery to show them you should get roughly what you are after.

At the moment liquid-fire (the go-to addon for animations in Ember) doesn't help with animating lists. There is a future underlying library designed to run beneath liquid-fire (https://github.com/ember-animation/ember-animated) which supports it, but it's not even alpha yet. If you are just getting started with Ember it would probably be best to steer clear of that for now ... 😉

Upvotes: 3

renno
renno

Reputation: 2827

What you need to look is about Promise(). This is an async call. It doesn't mean that after your element has been inserted that it will be ready. It can take 0.5s, 1s, 5s...

You should also look into ember-concurrency because it makes this kind of wokr much easier.

With that said you should do something like this:

leads: this.get('store').findAll('leads').then(function(leads) {
   //loaded
})

Also, if you are looking for animations take a look into liquid-fire

Upvotes: 0

Related Questions