我在Aurelia
创建了一个自定义元素,我也有valueChanged
,但是只有在自定义元素之外更改value
时才需要执行某个操作。由于签名是valueChanged(newValue, oldValue)
,我如何知道值何时从ViewModel
更改而不是从自定义元素本身更改? observer
或observable
以某种方式可行吗?
我实际上有一个工作样本,我发现当__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
的操作。如果不知道更改是否来自自定义元素的外部,我会进行递归调用而无法阻止它。我正在寻找的内容类似于以前的caller
和callee
,但是这已经被ES5和严格模式删除了,但这会非常有用。
仍在寻找答案:(
答案 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代码中确切地改变了值。我发现第一个选项可以得到最一致的结果。