ember.js - Ember Run Loop 和 Bootstrap 进度条

标签 ember.js

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

问题是,我认为所有更新进度条的调用都被退回到运行循环结束时的一个调用。

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

我对 ember run loop 了解不够,不知道如何在每一步更新栏。

我使用 Ember.run.next() 吗??

编辑:

所以我正在更新进度条:

$('#api_progress_bar .bar').width("#{amount}%")

amount 被传递给函数

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

但发生的情况是,我认为所有设置宽度的调用都被退回到一个调用...

我之前注意到像这样的 css mod 有时在控制权传回系统之前无法工作...

编辑 2:我添加了一个 jsbin来说明问题。发生的情况是 View 仅在操作中的所有代码完成时才会更新,这不是我想要的。我想谨慎地更新进度条。

有人知道如何做到这一点吗?

最佳答案

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

当模型更改时,进度条随着 View 绑定(bind)到该模型而更新。 Here's我是怎么做到的。模型中的实际值使用来自其他部分的事件进行更新,这里使用了 setInterval。

编辑:用 jsbin 更新问题后

this.set('progress') 调用被合并为一个调用,最后一个值由 Ember runloop 设置。这是一项重要的性能优化,有助于防止绑定(bind)在每个运行循环中仅针对给定属性触发一次。

要强制对 progress 调用进行排队,您需要将其包装在某种间隔中,或使用 Ember.run.scheduleOnce。即:- 立即增加步数计数器,然后使用间隔或 scheduleOnce 减慢计数。

这是一个示例 ProgressStepper。您在实例化时指定 totalSteps,并在步骤完成时调用 next。进度条可以绑定(bind)到它的 progress 属性。它使用 scheduleOnce,您可以使用 setInterval 设置为 100 毫秒来减慢速度。

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 .

关于ember.js - Ember Run Loop 和 Bootstrap 进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17609713/

相关文章:

ember.js - 如何从 Controller 访问模型?

ember.js - ember-cli 元配置/环境文件

javascript - 在 Ember.js 中使用 sendAction() 实现数据向下操作向上模式

ember.js - 无法获取 hasMany 关联

ember.js - 这是将 Reveal 与 Ember.js 一起使用的正确方法吗?

javascript - 观察数组 Controller 中 ItemController 的变化

javascript - EmberJS 可选参数

ember.js - 如何使用排序属性: ['lastName' ]

ember.js - 在 EmberJS 中检测 URL 更改并获取 URL(使用 Discourse)

linux - 尝试在 debian linux 上运行 ember 测试时出现奇怪的错误