Подписка на смену недвижимости с Aurelia

У меня есть свойство в моей модели представления, которое я хочу слушать и запускать события на основе его значения, например:

class viewModel {
  constructor() {
    this.value = '0';
    let val = 2;
    subscribe(this.value, callbackForValue);
    subscribe(val, callbackForVal);
  }
}

Это особенность Аурелии? Если да, то как мне настроить такую ​​подписку?


person Matthew James Davis    schedule 09.02.2015    source источник
comment
Я почти уверен, что это абстракция Аурелии?   -  person Matthew James Davis    schedule 10.02.2015
comment
На самом деле вы были первым, кто показал мне об Аурелии, но я уже знал об Object.oberve(), и когда я зашел на сайт Аурелии, он появился. Да, поэтому я не ответил, просто прокомментировал, извините, если это не помогло.   -  person Edwin Reynoso    schedule 10.02.2015
comment
@edwin Спасибо за вашу работу :) Так держать.   -  person Matthew James Davis    schedule 11.02.2015
comment
На самом деле вы можете использовать аннотацию @bindable для свойства, которое хотите наблюдать, и оно будет вызывать функцию [property name]Changed в классе модели представления при изменении значения свойства. Вероятно, это не то, для чего предназначался @bindable, но он работает.   -  person Decade Moon    schedule 25.06.2015
comment
@DecadeMoon, вероятно, аннотация @observable была разработана для той цели, о которой вы говорите.   -  person Fabio    schedule 06.10.2019


Ответы (4)


В некоторых плагинах я использовал DI для получения экземпляра ObserverLocator из контейнера:

import {inject} from 'aurelia-dependency-injection';  // or from 'aurelia-framework'
import {ObserverLocator} from 'aurelia-binding';      // or from 'aurelia-framework'

@inject(ObserverLocator)
export class Foo {
    constructor(observerLocator) {
        this.observerLocator = observerLocator;
    }
    ...
}

Затем вы можете сделать что-то вроде этого:

var subscription = this.observerLocator
    .getObserver(myObj, 'myPropertyName')
    .subscribe(myCallback);

Когда вы будете готовы избавиться от подписки, вызовите ее:

subscription();

Я думаю, что все это может быть изменено, но это то, что вы можете использовать прямо сейчас, если вам нужно.

Подробнее здесь

Обновление за октябрь 2015 г.

ObserverLocator — это внутренний API-интерфейс Aurelia «голого железа». Теперь есть общедоступный API для механизма привязки, который можно использовать:

import {inject} from 'aurelia-dependency-injection';  // or from 'aurelia-framework'
import {BindingEngine} from 'aurelia-binding';        // or from 'aurelia-framework'

@inject(BindingEngine)
export class ViewModel {
  constructor(bindingEngine) {
    this.obj = { foo: 'bar' };

    // subscribe
    let subscription = bindingEngine.propertyObserver(this.obj, 'foo')
      .subscribe((newValue, oldValue) => console.log(newValue));

    // unsubscribe
    subscription.dispose();
  }
}
person Jeremy Danyow    schedule 10.02.2015
comment
Не могли бы вы использовать функцию агрегатора событий Aurelia? - person Chi Row; 10.02.2015
comment
@ChiRow Пожалуйста, не злоупотребляйте EventAggregator! Его можно использовать в этом случае, но чаще всего, если вы думаете о подписчиках, вы думаете о тесно связанном поведении, а EventAggregator предназначен для слабосвязанного поведения. - person Matthew James Davis; 11.02.2015
comment
@jeremy-danyow молодец, давайте не забудем обновить это, когда API изменится :) - person Matthew James Davis; 11.02.2015
comment
@jeremy-danyow, в чем разница между propertyObserver и expressionObserver? - person smiggleworth; 25.08.2016
comment
propertyObserver наблюдает за определенным свойством (например, firstName) и уведомляет вас об изменении свойства. expressionObserver наблюдает за всем выражением (например, foo.bar[x][baz].hello() * test / something) и уведомляет вас, когда результат выражения изменяется. - person Jeremy Danyow; 25.08.2016
comment
Если другие найдут этот ответ, я хотел бы отметить, что есть небольшая разница с ответом @JeremyDanyow и другими. Он ответил, что было после ОП, как я могу наблюдать за изменениями свойств зависимости. Другие предоставленные ответы отвечают на следующее, как я наблюдаю изменения своих свойств. - person blandau; 01.11.2017

Согласно я убиваю ботаников, атрибут observable требует меньше затрат на привязку.

import {observable} from "aurelia-framework";

export class Example {

    @observable
    public description: string;

    private descriptionChanged(newValue: string, oldValue: string): void {

    }
}
person sharky101    schedule 02.09.2016

слушать и запускать события на основе его значения

Фрагмент кода с использованием TypeScript, надеюсь, это даст вам представление:

import {bindingMode} from "aurelia-binding";

export class Example{

    @bindable
    public description: string;

    private descriptionChanged(newValue: string, oldValue: string): void {
        console.log(newValue, oldValue);
    }
}

Имя метода должно соответствовать соглашению `${propertyName}Changed`


EDIT: Это именно то, что Decade Moon предложил в комментарии выше: Подписка на изменение свойства с Aurelia

person Mars Robertson    schedule 12.07.2016
comment
Мне больше всего нравится это решение. Он использует значительно меньше кода для выполнения той же задачи. - person JesseNewman19; 13.10.2016
comment
Это работает, потому что описание представляет собой строку. Приведенный выше метод не работает с объектами и массивами, как и исходный вопрос. Насколько я знаю. - person jafed; 31.10.2018

Декоратор @observable отлично подходит для этого сценария.

Вы можете использовать BindingEngine для просмотра коллекции или управления подпиской/отказом от подписки.

person Andrew    schedule 05.01.2017