aurelia变量观察者保持递归调用自己

时间:2017-10-10 19:21:07

标签: javascript aurelia aurelia-binding

我有一个可变更改订阅的递归问题。

@bindable year;

yearChanged(newVal, oldVal) {
  if (newVal) {
    this.year = this.year + '2017'; //just an example
  }
}

因此,您可以看到我使用Aurelia对话来监听变量的变化。当用户改变该变量的值时,我想在其末尾添加“2017”。

但是,当我更改year的值时,它会导致对同一个函数的递归调用。并且它一直调用相同的函数,直到应用程序崩溃。

Aurelia有办法阻止它这样做吗?谢谢

2 个答案:

答案 0 :(得分:1)

只要yearChanged属性发生更改,就会调用

year。您正在更改year回调中的yearChanged属性,因此您创建了一个无限循环。您应该注意,调用year时已经设置了yearChanged属性(回调是yearChanged而不是yearIsAboutToChange)。

我认为有很多方法可以解决这个问题。最简单的可能是在viewmodel上创建一个额外的属性。一个属性可绑定,可用于更改检测,另一个属性可用于显示目的。

@bindable year;
displayYear;

yearChanged(newVal, oldVal) {
  if (newVal) {
    this.displayYear = this.year + '2017'; //just an example
  }
}

您还可以缩短周期:

@bindable year;

yearChanged(newVal, oldVal) {
  if (newVal && oldVal + '2017' !== newVal) {
    this.year = this.year + '2017'; //just an example
  }
}

同样,如果没有更多的上下文,很难说,但是根据您提供的代码,Value Converter很可能是您真正想要的。

答案 1 :(得分:0)

如果仅仅出于表示的目的,我会选择价值转换器。 当你需要这样做时(包装第三方组件)仍有合法的情况。然后,您可以执行以下操作:

import {TaskQueue} from 'aurelia-task-queue';
import {inject} from 'aurelia-dependency-injection';

@inject(TaskQueue)
class MyCustomElement {
  constructor(queue) {
    this.queue = queue;
  }

  setPropertyOfInterestInternally(value) {
    this.internalSet = true;
    // setting the property here will make the 
    // the underlying mechanics to enqueue a task
    // on the micro task queue - to invoke the change handler
    // it will not be invoked in the current call stack
    this.propertyOfInterest = value;
    // we schedule another task on the micro task queue
    // the arrow function(task) will run after the change handler
    this.queue.queueMicroTask(() => this.internalSet = false);
  }

  propertyOfInterestChanged() {
    // if the set is internal => skip
    if (this.internalSet) { return; }
    // ...
  }
}

任务同步执行 - 他们 等待 async 工作。