Emberjs :如何在模型操作上显示加载微调器和通知消息



我正在使用 ember.js 1.2 并在尝试在我的模型上进行 crud 操作期间显示加载微调器和通知消息时遇到问题。

这是代码:

var MyModelController = Ember.ObjectController.extend({
  needs: ['application'],
  application: Ember.computed.alias("controllers.application"),
  actions: {
    save: function() {
      var _this = this;
      // Display the spinner
      this.get('application').get('loading').trigger(true);
      this.get('model').save().then(function(response) {
        // Hide the spinner
        _this.get('application').get('loading').trigger(false);
        // Display the success message
        _this.get('application').get('flash').success('The model has been updated.');
      }, function(response) {
        // Hide the loading spinner
        _this.get('application').get('loading').trigger(false);
        // Display the error message
        _this.get('application').get('flash').danger('Error updating the model.');
      });
    }
  }
});

这里有两个主要问题:

  • 第一:微调器以需要 0.5 秒的平移显示,但保存操作以较少的持续时间执行,并且微调器显示并立即消失。在这里,我想在我的模型上调用保存操作之前设置一个 1s 计时器,以确保正确执行动画。怎么可能?

  • 第二:我的flash对象上的成功方法绑定到模板上的特定{{view.message}}。如果我在 promise 的"then"之外调用此方法,则消息显示得很好,但就我而言,绑定并没有完成。我是否错过了使用承诺的方式?怎么可能显示此消息?

您需要

实现加载路由

http://emberjs.com/guides/routing/loading-and-error-substates/

https://gist.github.com/machty/6944577

关于加载微调器:kingpin2k给出了一种解决方案。当承诺需要很多时间才能返回时,将调用旧版 LoadRoute。所以我是这样写的:

var ApplicationRoute = Ember.Route.extend({
  actions: {
    loading: function() {
      var _app = this.controllerFor('application');
      _app.get('loading').trigger(true);
      this.router.one('didTransition', function() {
        _app.get('loading').trigger(false);
      });
    }
  }
});

然后在路线上,我强迫我的承诺至少需要 500 毫秒才能返回。因此,将显示动画微调器,并且 UI 已正确更新。

model: function() {
  var _this = this;
  return new Ember.RSVP.Promise(function(resolve) {
    setTimeout(function() {
      resolve(_this.get('store').find('model'));
    }, 500);
  });
},

这种方式适用于通过路由的模型钩子获取数据。但是为了从保存按钮更新模型,我编写了一个实现保存操作的特定模型控制器;然后我所有管理单个资源的控制器都扩展了它:

var ModelController = Ember.ObjectController.extend({
  needs: ['application'],
  updateOKMessage: null,
  updateKOMessage: null,
  application: Ember.computed.alias("controllers.application"),
  actions: {
    save: function() {
      var _this = this;
      var _app = _this.get('application');
      // Display the loading spinner
      _app.get('loading').trigger(true);
      // Wait during 500ms to let the animation occurs
      setTimeout(function() {
        // Save the model
        _this.get('model').save().then(function(response) {
          setTimeout(function() {
            // Set the message of the flash from a timeout
            // if not, the message does not appear
            _app.get('flash').success(_this.get('updateOKMessage'));
          }, 100);
        }, function(response) {
          setTimeout(function() {
            // Same issue (or maybe it is not an issue)
            _app.get('flash').danger(_this.get('updateKOMessage'));
          }, 100);
          if(response.status === 422) {
            _this.get('model').set('errors', response.responseJSON.errors);
          }
        }).then(function() {
          setTimeout(function() {
            _app.get('loading').trigger(false);
          }, 600);
        });
      }, 500);
    }
  }
});

我纠正了从计时器回调而不是从承诺的返回方法设置它们的闪存消息的问题。

我的解决方案非常简单,而不是我想的"余烬"方式。 但它工作得很好,不会生成太多的新文件/帮助程序:

应用/路由/应用程序.js

import Ember from 'ember';
export default Ember.Route.extend(Ember.Evented, {
  actions: {
    loading: function() {
      // enable/disable spinner when model is loading slow
      Ember.$('#blur').css('-webkit-filter', 'blur(3px)')
      Ember.$('#spinner').css('display', 'flex')
      this.router.one('didTransition', function() {
        Ember.$('#blur').css('-webkit-filter', 'blur(0px)')
        Ember.$('#spinner').css('display', 'none')
      });
    }
  }
});

最新更新