1

I'd like to show a loading symbol while my validation is processing. My .hbs file looks like this

<div {{bind-attr class='isProcessing:spinner'}}></div>

I tried to wrap my validations into the afterRender run loop, but apparently afterRender doesn't mean after-CSS. My validations are executed before the css class of the div changes (It doesn't change at all).

App.PostController = Em.Controller.extend({

    isProcessing: false,

    actions: {

        savePost: function() {

            this.set('isProcessing', true);

            Ember.run.scheduleOnce('afterRender', this, function() {

                // do a lot of validating and other (non-asynchronous) stuff here
                // ... this may take several seconds

                this.set('isProcessing', false);
            });
        }
    }
});

What can I do that my code starts to execute after all CSS rendering is done?

I also tried Ember.run.next. This doesn't work either. Ember.run.later works with a timeout of at least about 200ms but of course I don't want to hardcode any static timespan.

UPDATE: Here is a js-fiddle for my problem: http://jsfiddle.net/4vp2mxr0/2/

Any help would be apprechiated! Thanks in advance!

  • Why are you wrapping your async stuff in `Ember.run.scheduleOnce` at all? This is not necessary. You only need to make sure that the `isProcessing` property is set to `false` once the async operations are finished but there is no need to delay this. – vanthome Jan 23 '15 at 18:22
  • thanks for your reply. Unfortunately my validations are **not** async. Ember seems to update the class-binding only after everything (synchronous work) is done – user3200478 Jan 24 '15 at 11:12
  • No, Ember will update any computed property immediately once its value changes. But you need to declare it as a computed property. Please see [here](http://emberjs.com/guides/object-model/computed-properties/) how to do this. – vanthome Jan 24 '15 at 11:15
  • A class-binding is a computed property, or not? And how can I make that isProcessing is a computed property? I don't want it to be computed, I want to set it by myself. My understanding is that Ember updates computed properties immediately ('sync'-queue), but finishes my function ('actions'-queue) before it re-renders/applies content- or class-bindings the template ('render'-queue). That's because I try to wrap it into the run loop. I updated my question with a js-fiddle, hopefully this will clarify the situation. Thanks for your help! – user3200478 Jan 24 '15 at 12:09

1 Answers1

0

Please wrap your code in Ember.run.next. Like this:

savePost: function() {

    this.set('isProcessing', true);
    Em.run.next(this, function() {
        //just some synchronous code that takes some time (the time inbetween the two alerts)
        var i=0,a;
        alert('start code');
        while (i++ < 10000000) {
            a = Math.pow(i, Math.pow(1/i, Math.sin(i)))/3/4/5/5 * Math.log(i);
        }
        this.set('isProcessing', false);
        alert('finished code');
    }); 
}

It works as intended. I think your problem is that you set isProcessing to true and then immediately set it to false, because you don't wait for async code/promises to complete. In this case you have to set isProcessing to false when promises are resolved. If this is only one promise you can set isProcessing to false inside .then(), for example:

myModel.get('children').then (children) =>
  @set 'isProcessing', false

Or if you resolve multiple promises, or you resolve promises inside a loop, you can use Ember.run.debounce which will fire after XXXms after last call to this method, for example:

finishProcessing: ->
  @set 'isProcessing', false

actions:
  savePost: ->
    myModel.get('children').then (children) =>
      children.forEach (child) =>
        child.then (resolvedChild) =>
          Ember.run.debounce @, 'finishProcessing', 500
Daniel Kmak
  • 18,164
  • 7
  • 66
  • 89