Как подписаться на переменные изменения? - PullRequest
0 голосов
/ 23 октября 2018

Я объявил следующую переменную:

public filter: IFilterWeekScheduleClassShort = {};

Как подписаться на изменения (фильтр прослушивания объекта)?

Я пробовал это:

private filter: IFilterWeekScheduleClassShort = {};
private filterChanges: BehaviorSubject<IFilterWeekScheduleClassShort> = new BehaviorSubject(this.filter);

this.filterChanges.subscribe((model) => {
    console.log(model);
});

Естьэто нормально?

Мой окончательный код:

public _filter: IFilterWeekScheduleClassShort = {};
private filterChanges: BehaviorSubject<IFilterWeekScheduleClassShort> = new BehaviorSubject(this._filter);

  this.filter = {a: 1, b: 2}

  set filter(value: any) {
    this._filter = value;
    this.filterChanges.next(this._filter);
  }

  get filter() {
    return this.filterChanges.asObservable();
  }

Подписаться на:

this.filter.subscribe(model => {
   console.log(model);
});

Изменения, которые я делаю из формы:

[(ngModel)]="_filter.teacherId"

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

Я думаю, что закрытие, которое вы хотите получить, использует scan():

const filterChanges$ = new Subject()
const defaultFilter = {}

const filter$ = filterChanges$
  .pipe(
    scan((acc, mergeFilter) => {
      return {
        ...acc,
        ...mergeFilter,
      }
    }, defaultFilter)
  )

filter$.subscribe(console.log);

filterChanges$.next({ name: 'abc' })
filterChanges$.next({ num: 42 })
filterChanges$.next({ name: 'xyz' })

Демонстрация в реальном времени: https://stackblitz.com/edit/rxjs6-demo-ngqkzv?file=index.ts

Это выдаст:

{name: "abc"}
{name: "abc", num: 42}
{name: "xyz", num: 42}

Некоторое время назад я создал небольшую оболочку вокруг window.Proxy под названием rxjs-observable-object, которая позволяет вам обернуть любой объект и затем прослушать изменения на нем (https://github.com/martinsik/rxjs-ds#object):

import { map } from 'rxjs/operators';
import { ObservableObject } from 'rxjs-observable-object';

const defaultFilter = {}
const { proxy, events } = new ObservableObject(defaultFilter);

const filter$ = events.onSet
  .pipe(
    map(({ target }) => target)
  )

filter$.subscribe(console.log);

proxy['name'] = 'abc';
proxy['num'] = 42;
proxy['name'] = 'xyz';

Демонстрация в реальном времени: https://stackblitz.com/edit/rxjs6-demo-hojjkk?file=index.ts

Однако rxjs-observable-object немного устарел и требует также установленного пакета rxjs-comapt.

Вывод для обоих примеров одинаков.

0 голосов
/ 23 октября 2018

Создайте сеттер

private _filter: IFilterWeekScheduleClassShort = {};
set filter(value) {
  this.doSomethingOnVariableChange(value);
  this._filter = value;
}

Теперь вы можете использовать его следующим образом

this.filter = 'x';

И ваша функция doSomethingOnVariableChange будет вызываться с 'x'.

С наблюдаемой:

private _filter: IFilterWeekScheduleClassShort = {};
private _filter$ = new BehaviorSubject(this._filter);
set filter(value) {
  this._filter = value;
  this._filter$.next(this._filter);
}
get filter() {
  return this._filter$.asObservable();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...