Ember.js - afterRender fires before CSS is finished

爷,独闯天下 提交于 2019-12-24 11:26:38

问题


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!


回答1:


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


来源:https://stackoverflow.com/questions/28116138/ember-js-afterrender-fires-before-css-is-finished

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!