Как узнать значение происхождений в Аурелии?

Я создал пользовательский элемент в 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

Надеюсь это поможет!

Другие вопросы по тегам