Я объявил следующую переменную:
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 ответа
Сделать сеттер
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();
}
Я думаю, что то, что вы хотите получить, использует 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 ? файл = 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 ? файл = index.ts
Однако rxjs-observable-object
сейчас немного устарел и требует также установленного пакета rxjs-comapt
.
Результат для обоих примеров одинаков.
Похожие вопросы
Новые вопросы
angular
Вопросы по Angular (не путать с AngularJS), веб-фреймворку от Google. Используйте этот тег для угловых вопросов, которые не относятся к конкретной версии. Для более старой веб-платформы AngularJS (1.x) используйте тег angularjs.