从触发的动作运行Ember.run.later

时间:2018-12-30 17:42:42

标签: javascript ember.js handlebars.js ember-concurrency

我在Ember控制器中的动作处理有问题。我想在hbs中单击 edit (按钮)后连续运行某些功能。我已经在操作中尝试过这种方式。

openEditWindow() {
  this.set('someChangingValue', true);
},

这是对动作someChangingValue的变化做出反应的功能。

someChangingValue: false,
  someTestFunction: observer('someChangingValue', function() {
  var test = this.get('someChangingValue');

  if(test === true){
    Ember.run.later((function() {
      this.functionThatIsRunningEachTwoSeconds();
    }), 2000);
  } else {
    console.log('this should not do anything');
  }
}),

但这仅运行functionThatIsRunningEachTwoSeconds一次。还尝试过将someChangingValue更改为false的相同功能(如果true,否则将我置于观察属性的无限循环中。

谢谢!

2 个答案:

答案 0 :(得分:0)

Ember.run.later仅运行一次功能。 docs

中明确指出

此外,您是否使用很旧的余烬版本? Ember.run.later已过时,您应该使用部分导入import { later } from '@ember/runloop';代替

关于您的任务,至少有两种方法

使用ember-concurrency插件

安装ember-concurrency并写入控制器:

import { task, timeout } from 'ember-concurrency';

export default Controller.extend({
  infiniteTask: task(function* () {
    while(true) {
      this.functionThatIsRunningEachTwoSeconds();
      yield timeout(2000);
    }
  }).drop(),
});

模板:

{{#if infiniteTask.isIdle}}
  <button onclick={{perform infiniteTask}}>Start</button>
{{else}}
  <button onclick={{cancel-all infiniteTask}}>Stop</button>
{{/if}}

此插件在很多情况下都非常有用,请阅读文档以了解您为什么会需要它

创建一个可以递归调用自身的函数

这是重复执行某些操作的经典JS方法,但是在普通JS中,我们使用setTimeout而不是余烬的later

import { later, cancel } from '@ember/runloop';

export default Controller.extend({
  infiniteFuction() {
    this.functionThatIsRunningEachTwoSeconds();
    this.set('infiniteTimer', later(this, 'infiniteFuction', 2000));
  },
  startInfiniteFunction() {
    //clear timer as safety measure to prevent from starting few 
    //"infinite function loops" at the same time
    cancel(this.infiniteTimer);
    this.infiniteFuction();
  },
  stopInfiniteFunction() {
    cancel(this.infiniteTimer);
    this.set('infiniteTimer', undefined);
  }
});

模板:

{{#unless infiniteTimer}}
  <button onclick={{action startInfiniteFunction}}>Start</button>
{{else}}
  <button onclick={{action stopInfiniteFunction}}>Stop</button>
{{/unless}} 

答案 1 :(得分:0)

仅是为了弄清当前代码有什么问题(不一定将其作为解决方案),您必须更改值以使观察者触发。如果您将值设置为CarController,然后在以后再次将其设置为public class CarController : MonoBehaviour { // Somehow get the reference for this either by referencing it or finding it on runtime etc // I will asume this is already set public LongPressButton longPressButton; private void Awake() { // make sure listener is only added once longPressButton.onLongPress.RemoveListener(Update); longPressButton.onLongPress.AddListener(Update); } private void Update() { rotation = Input.GetAxisRaw("Horizontal"); movement = -Input.GetAxisRaw("Vertical") * speed; } private void OnDestroy() { // clean up the listener longPressButton.onLongPress.RemoveListener(Update); } //... } ,而从未将其设置为% Find outliers meanValue = mean(data_banknote_authentication(:,1:4)); absoluteDeviation = abs(data_banknote_authentication(:,1:4) - meanValue); mad = median(absoluteDeviation); sensitivityFactor = 3 % I am not sure if this is correct thresholdValue = sensitivityFactor * mad; outlierIndexes = abs(absoluteDeviation) > thresholdValue outliers = data_banknote_authentication(:,1:4)(outlierIndexes); nonOutliers = data_banknote_authentication(:,1:4)(~outlierIndexes); % Remove outliers for i=1:1372 for k=1:4 if (outlierIndexes(i,k) == 1) data_banknote_authentication(i,k) = ' '; %data_banknote_authentication(i,k) = " "; endif endfor endfor ,则Ember将在内部忽略此值,并且不会重新激发观察者。请参见此twiddle,以查看使用观察者的可行示例。

代码是

this.geolocation.getCurrentPosition().then( pos =>{

      this.lat = pos.coords.latitude;     
      this.long = pos.coords.longitude;
}).catch(err => this.presentToast(err));

现在您知道您当前的方法有什么问题,让我重新记录一下,并建议这不是编排重复循环的好方法。我也建议使用Ember-Concurrency,因为它可以识别Ember生命周期。

如果您处理了路线中的“编辑”按钮,则可以在更改路线时超级干净地取消它

true

停用对应于余烬deactivate路线挂钩/事件:

  

当路由器完全退出此路由时,将执行此挂钩。它   更改路径模型时不执行。