如何观察RxJS中的属性变化?

时间:2017-08-14 11:55:30

标签: javascript angularjs rxjs

我对RxJS没有多少经验,但我想知道是否有办法订阅对象属性更改? 我正在使用RxJS 5.我使用BehaviorSubject将新值推送给订阅者。主题包含定义某些应用程序设置的对象。

所以,我想要做的是,我想要一个应用程序组件订阅并在特定属性更改时获取新值。 或者,我希望observable为每个订阅者生成一个对象的副本 - 因此他们没有对原始对象的引用。

我的问题类似于this one

提供应用程序设置的服务:

app.factory('settingsProvider', ['$rootScope', function ($rootScope) {

    let subject = new Rx.BehaviorSubject();

    let updateSettings = function (obj) {

        subject.next(_.merge({}, subject.getValue(), obj));
    };

    return {

        updateSettings: updateSettings,
        getObservable: function () {

            return subject.asObservable();
        }
    };
}]);

在某些指令中,我不想订阅某些属性的更改。 我目前有这个:

let settings = {};
let settingsSubscription = settingsProvider.getObservable().subscribe(x => settings = x);

1 个答案:

答案 0 :(得分:0)

我相信您想要操作员distincthttps://rxjs-dev.firebaseapp.com/api/operators/distinct

这是一个古老的问题,因此我将提供v6语法并假设您在此同时进行了更新。概念没有改变,因此您可以在v5中应用此方法。

您正在犯的一个大错误是迫使settings在上面重新分配为闭包。可观察变量最适合作为流,您将其中一个可观察变量通过管道传输到下一个变量,并且没有副作用。如果我们假设您开始观察构建{ foo: 1, bar: 2, baz: 3}之类的东西,则可以先map取出所需的道具,然后distinct在其上以确保我们仅在更改时发出。

const fooUpdate$ = mySub$
  .pipe(
    .map(({ foo }) => foo)
    .distinct()
  );

fooUpdate$.subscribe(val => console.log(val));

// Example of testing it
mySub$.next({ foo: 1, bar: 2 });
mySub$.next({ foo: 1, bar: 3 });
mySub$.next({ foo: 2, bar: 4 });
mySub$.next({ foo: 2, bar: 5 });
mySub$.next({ foo: 2, bar: 5 });
mySub$.next({ foo: 3, bar: 2 });

// 1, 2, 3