Emberjs更新/观察员/运行循环

时间:2014-06-18 12:42:19

标签: javascript ember.js

我有一个观察属性(数组)的控制器,每次更改时,都会在服务器上调用一个昂贵的函数,然后显示结果。

在初始控制器设置中(在路径中),我需要循环遍历数组并设置一些值 - 即

something.forEach(function(el) { myArrayProperty.set(el.id, true); });

这是通过forEach在每个循环上触发观察者。如何循环forEach,更新所有元素,然后允许Ember观察者开火?

我已经尝试了scheduleOnceEmber.run(function() {..}),但我似乎无法让它发挥作用。

谢谢!

2 个答案:

答案 0 :(得分:2)

解决这个问题的一种方法是限制或去除观察阵列的昂贵功能。

请参阅Ember.run.debounce

E.g。你现在有这个:

App.MyController = Ember.ArrayController.extend({
  myExpensiveObserver: function() {
    /* some expensive computations */
  }.observes('content.@each.id'),
});

...而你改为:

App.MyController = Ember.ArrayController.extend({
  myExpensiveObserver: function() {
    Ember.run.debounce(this, this.myExpensiveObserverImpl, 300);
  }.observes('content.@each.id'),
  myExpensiveObserverImpl: function() {
     /* some expensive computations */
  },
});

(用重新计算之间的最小间隔替换300。)

之间存在细微差别 Ember.run.debounceEmber.run.throttle, 你可能更喜欢其中一个而不是另一个。 但是,根据您的描述,听起来任何人都可以满足要求。

正如@ kingpin2k指出的那样,要小心你传入去抖动或踩踏的功能。 它不能是匿名的,因为Ember每次调用时都无法确定它们是否确实相同。

答案 1 :(得分:1)

bguiz是完全正确的,扼杀或去抖它。限制将允许它每隔x毫秒运行一次,并且去抖将阻止它运行直到它没有运行x毫秒。在另一个答案中遗漏的一个小细微差别是Ember通过比较传递函数来跟踪去抖/节流的方式。因此,每次传递一个匿名函数只会继续发射而不会进行限制/去抖动。

App.MyController = Ember.ArrayController.extend({
  myExpensiveObserver: function() {
    Ember.run.debounce(this, this.realWorker, 300);
  }.observes('content.@each.id'),
  realWorker: function(){
    console.log("I'm working");
  },
  myExpensiveObserverThrottle: function() {
    Ember.run.throttle(this, this.realWorkerThrottle, 300);
  }.observes('content.@each.id'),
  realWorkerThrottle: function(){
    console.log("I'm working");
  }
});

示例:http://emberjs.jsbin.com/cixawagi/1/edit