我有一个观察属性(数组)的控制器,每次更改时,都会在服务器上调用一个昂贵的函数,然后显示结果。
在初始控制器设置中(在路径中),我需要循环遍历数组并设置一些值 - 即
something.forEach(function(el) { myArrayProperty.set(el.id, true); });
这是通过forEach
在每个循环上触发观察者。如何循环forEach
,更新所有元素,然后允许Ember观察者开火?
我已经尝试了scheduleOnce
和Ember.run(function() {..})
,但我似乎无法让它发挥作用。
谢谢!
答案 0 :(得分:2)
解决这个问题的一种方法是限制或去除观察阵列的昂贵功能。
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.debounce 和Ember.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");
}
});