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

时间:2013-12-19 16:47:28

标签: javascript binding ember.js ember-data promise

我正在使用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}}。如果我在'之外调用此方法,那么'承诺,消息很好地显示,但在我的情况下,它不是没有完成绑定。我是否错过了使用承诺的方式?怎么可能显示这条消息?

3 个答案:

答案 0 :(得分:6)

答案 1 :(得分: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);
      });
    }
  }
});

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

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

这种方式适用于通过路径的模型钩子获取数据。但是为了从保存按钮更新模型,我编写了一个实现保存操作的特定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);
    }
  }
});

我使用flash消息更正了问题,这些消息是通过计时器回调设置的,而不是来自promise的return方法。

答案 2 :(得分:0)

我的解决方案很简单,而不是' ember'我想的方式。但它工作得很好,并没有产生太多的新文件/助手:

的应用程序/路由/ application.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')
      });
    }
  }
});