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

obo*_*obo 6 javascript binding promise ember.js ember-data

我正在使用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.');
      });
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

这里有两个主要问题:

  • 首先:显示微调器,其转换时间为0.5秒,但保存操作的持续时间较短,微调器显示并立即消失.这里我想在我的模型上调用保存操作之前设置一个1s计时器,以确保正确执行动画.怎么可能呢?

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

obo*_*obo 2

关于加载旋转器:kingpin2k 提供了一种解决方案。当承诺需要很长时间才能返回时,会调用旧版 LoadingRoute。所以我这样写:

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);
      });
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

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

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

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

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);
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

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