如何知道奥里利亚的价值变化?

时间:2017-07-06 17:04:09

标签: javascript javascript-events aurelia aurelia-binding

我在Aurelia创建了一个自定义元素,我也有valueChanged,但是只有在自定义元素之外更改value时才需要执行某个操作。由于签名是valueChanged(newValue, oldValue),我如何知道值何时从ViewModel更改而不是从自定义元素本身更改? observerobservable以某种方式可行吗?

我实际上有一个工作样本,我发现当__array_observer__value更改时,还有一个ViewModel属性,但它可以工作,但它可能并不理想。所以我得到了这段有用的代码

valueChanged(newValue, oldValue) {
  if (newValue !== oldValue && newValue.__array_observer__) {
    // value got changed outside of this custom element
  }
}

这可能不太理想,或者是吗?知道value在自定义元素之外的位置发生变化的任何其他建议吗?

修改

尽可能地,我正在寻找一种仍然可以访问自定义元素的解决方案。即使我想通过外部值更改调用触发,我仍然需要调用相同自定义元素的内部函数。

编辑#2

为了更详细地说明我的问题,我需要知道value何时从外部进行了更改,因为这会触发一个会重新影响value的操作。如果不知道更改是否来自自定义元素的外部,我会进行递归调用而无法阻止它。我正在寻找的内容类似于以前的callercallee,但是这已经被ES5和严格模式删除了,但这会非常有用。

仍在寻找答案:(

2 个答案:

答案 0 :(得分:2)

您可以使用 CustomBindingBehavior 拦截updateTarget事件。例如:

export class InterceptBindingBehavior {
  bind(binding, scope, interceptor) {
    binding['originalUpdateTarget'] = binding['updateTarget'];
    binding.updateTarget = val => { 
      alert('property was changed outside of the element');
      //do something here
      binding['originalUpdateTarget'](val);   
    }
  }

  unbind(binding, scope) {
    binding.updateTarget = binding['originalUpdateTarget'];
    binding['originalUpdateTarget'] = null;
  }
}

用法:

<template>
  <require from="./intercept-binding-behavior"></require>

  <some-element value.bind="message & intercept"></some-element>
</template>

可运行的示例:https://gist.run/?id=bcd7d39ed94856caf586f224f89fd1ff

我在很多情况下都没有测试过,我不确定这是不是最好的方法。

如果你想做相反的事情(当从元素而不是VM更改属性时拦截),只需将updateTarget替换为updateSource

有关 CustomBindingBehaviors http://aurelia.io/hub.html#/doc/article/aurelia/binding/latest/binding-binding-behaviors/8

的详细信息

希望这有帮助!

答案 1 :(得分:1)

正如gitter中所讨论的,您可以使用抑制标志

value: number;
suppressValueChanged: boolean;
valueChanged(){
  if(this.suppressValueChanged){
    this.suppressValueChanged = false;
    this.logger.debug("the value has been changed from inside the element");
    return;
  }
  this.logger.debug("the value has been changed from outside the element");
  // here comes the code to run when the value is changed outside
}

internalSetValue(value: number){
  this.suppressValueChanged = true;
  this.value = value;
}

我在changed方法中重置标志的原因是,根据情况{A}可以异步调用valueChanged,因此您不能只执行以下操作

  this.suppressValueChanged = true;
  this.value = 123;
  this.suppressValueChanged = false;

有时,使用任务会有效

  this.taskQueue.queueTask(() => {
    this.suppressValueChanged = true;
    this.value = 123;
    this.suppressValueChanged = false;
  });

这实际上取决于您在Aurelia代码中确切地改变了值。我发现第一个选项可以得到最一致的结果。