Aurelia custom Binding Behavior для наблюдения ВСЕХ свойств объекта - PullRequest
0 голосов
/ 05 ноября 2018

Я хотел бы создать пользовательское поведение привязки, которое позволяет обнаруживать ЛЮБЫЕ изменения свойств объекта, например:

<my-form model.bind="myObject & objectObserver:myObjChanged()"></my-form>

Я знаю, что могу использовать механизм связывания Aurelia для создания наблюдателя свойств, и, возможно, я могу встроить его в пользовательское поведение привязки, чтобы обнаруживать свойства объекта и создавать наблюдатели свойств для каждого из них. Но я не могу понять смысл связывающего объекта, который дан мне в обычном поведении связывания. Вот мой код:

import { inject, bindingBehavior, BindingEngine } from 'aurelia-framework';

@bindingBehavior('objectObserver')
@inject(BindingEngine)
export default class ObjectObserverBindingBehavior {
  constructor(bindingEngine) {
    this.bindingEngine = bindingEngine;
  }

  bind(binding, scope, interceptor) {
    console.warn('hello', binding, scope, interceptor);
  }

  unbind(binding, scope) {
    console.warn('observer.unbind()', binding, scope);
  }
}

Когда происходит связывание и выводится консольный текст, я вижу enter image description here

Так что я знаю, что это работает, но я не знаю, как лучше всего начать смотреть. Я вижу связанный объект внутри targetObserver.currentValue. Это лучшее свойство, чтобы начать смотреть? Есть ли другой способ, который использует существующую функциональность Aurelia Binding Engine?

1 Ответ

0 голосов
/ 05 ноября 2018

Я нашел решение, не относящееся к Aurelia, основанное на функциональности Proxy , встроенной в Javascript.

export function onChangeObj(object, onChange) {
  // creates Proxy to detect changes in object properties and call a function
  if (typeof onChange !== 'function' || typeof object !== 'object') {
    throw new Error('onChangeObj: incorrect parameters');
  }
  const handler = {
    set(obj, prop, value) {
      onChange(prop, value);
      return Reflect.set(obj, prop, value);
    },
  };
  return new Proxy(object, handler);
}

Чтобы использовать это, просто назовите это так:

this.myObject = onChangeObj(this.myObject, () => this.myObjChanged());

Фактически объект заменяется прокси-сервером-оболочкой, который вызывает предоставленную функцию каждый раз, когда изменяется одно из свойств (с помощью установщика).

Если кто-нибудь найдет решение через Aurelia Binding Behavior, мне все равно будет интересно.

...