Ember Run循环和Bootstrap进度条

时间:2013-07-12 07:29:16

标签: ember.js

我在ember应用程序启动时执行了一些操作,并希望在每个步骤完成时显示一个twitter bootstrap进度条。

问题在于我认为所有更新进度条的调用都会在运行循环结束时被弹回一个调用。

进度条只有在一切都完成后才会更新到100%。

我对ember run循环知之甚少,知道如何更新每一步的栏。

我是否使用Ember.run.next()??

编辑:

所以我用以下内容更新进度条:

$('#api_progress_bar .bar')。width(“#{amount}%”)

并将金额传递给函数

上述行之间采取的步骤基本上是创建一些种子数据Ember模型,没有什么不寻常的。

但正在发生的事情是,我认为设定宽度的所有调用都被反弹到一个电话......

我之前注意到,在将控制权传递回系统之前,有时这样的CSS修改无效...

编辑2:我添加了jsbin来说明问题。发生的情况是,只有当操作中的所有代码完成时,视图才会更新,这不是我想要的。我想以谨慎的步骤更新进度条。

任何想法如何做到这一点?

2 个答案:

答案 0 :(得分:2)

这可能取决于进度任务的完成速度。我目前正在ProgressView中使用具有progress属性的相应模型进行更新。

当视图绑定到此模型时,模型更改进度条更新。 Here's我是怎么做到的。模型中的实际值使用其他部分的事件进行更新,此处使用setInterval。

编辑:用jsbin

更新问题后

this.set('progress')次调用将折叠为一个调用,其中最后一个值由Ember runloop设置。这是一项重要的性能优化,有助于防止绑定仅针对每个runloop的给定属性触发一次。

要强制progress调用排队,您需要以某种间隔包装它,或使用Ember.run.scheduleOnce。即: - 立即增加一个步数计数器,然后用间隔或scheduleOnce来减慢计数。

以下是ProgressStepper的示例。您在实例化时指定totalSteps,并在步骤完成时调用next。进度条可以绑定到它的progress属性。它使用scheduleOnce,你可以用setInterval表示更慢的速度,比如100ms。

App.ProgressStepper = Em.Object.extend({
  totalSteps: 10,
  currentStep: 0,
  progress: 0,
  complete: Ember.K(),
  pending: 0,
  isOnRunloop: false,

  next: function() {
    this.set('pending', this.get('pending') + 1);
    if (!this.get('isOnRunLoop')) {
      this.set('isOnRunLoop', true);
      this.enqueue();
    } 
  },

  enqueue: function() {
    // ticking on the runloop gives better performance 
    // as it doesn't use additional timers
    Ember.run.scheduleOnce('afterRender', this, 'onNext');

    // use this is if you want to tick slower
    //setTimeout(this.onNext.bind(this), 100);
  },

  onNext: function() {
    this.nextStep();

    if (this.hasPending()) {
      this.enqueue();
    } else {
      this.set('isOnRunLoop', false);
    }
  },

  hasPending: function() {
    return this.get('pending') > 0;
  },

  nextStep: function() {
    this.set('pending', this.get('pending') - 1);

    var currentStep = this.get('currentStep');
    var totalSteps = this.get('totalSteps');
    currentStep++;

    if (currentStep <= totalSteps) {
      this.set('currentStep', currentStep);
      this.updateProgress();

      if (currentStep == totalSteps) {
        Ember.run.scheduleOnce('afterRender', this, 'complete');
      }
    }
  },

  updateProgress: function() {
    var progress = this.get('currentStep') / this.get('totalSteps') * 100;
    this.set('progress', progress);
  }
});

这是一个更新的jsbin

答案 1 :(得分:2)

看看:

github:https://github.com/ember-addons/bootstrap-for-ember 演示:http://ember-addons.github.io/bootstrap-for-ember

它支持bootstrap进度条组件,无需任何接线代码即可轻松绑定到控制器。