Как узнать значение происхождений в Аурелии?
Я создал пользовательский элемент в 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 и строгим режимом, однако это было бы очень полезно.
Все еще ищу ответ:(
2 ответа
Как уже говорилось в 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
Метод заключается в том, что в зависимости от обстоятельств valueChanged
может вызываться Аурелией асинхронно, поэтому вы не можете просто сделать следующее
this.suppressValueChanged = true;
this.value = 123;
this.suppressValueChanged = false;
Иногда использование задачи будет работать
this.taskQueue.queueTask(() => {
this.suppressValueChanged = true;
this.value = 123;
this.suppressValueChanged = false;
});
Это действительно зависит от того, где именно в коде Aurelia вы меняете значение. Я обнаружил, что первый вариант дает наиболее последовательный результат.
Вы можете использовать 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
Я не проверял это во многих случаях, и я не уверен, что это лучший способ.
Если вы хотите сделать обратное (перехват, когда свойство изменяется от элемента вместо виртуальной машины), просто замените updateTarget
за updateSource
,
Больше информации о CustomBindingBehaviors http://aurelia.io/hub.html#/doc/article/aurelia/binding/latest/binding-binding-behaviors/8
Надеюсь это поможет!