Generic RxJS object for bidirectional data binding in Angular 2

I have an oneton service for app settings

class Setting {
  get foo() {
    return storage.get('foo');
  }

  set foo(val)
    storage.set('foo', val);
  }
}

which is related in the component views as setting.foo.

Since calls storagecan be expensive and because they can be asynchronous, I would rather replace getter / setter with an RxJS theme that could update and read storagewhenever needed.

So, I will reorganize it into

class Setting {

  constructor() {
    this.fooSubject = new ReplaySubject(1);

    fooSubject.subscribe((val) => {
      storage.set('foo', val);
    });

    this.foo$ = this.fooSubject
    .map(() => storage.get('foo'))
    .publishReplay(1).refCount();
}

and using it like setting.foo$ | asyncand setting.fooSubject.next(newFoo). Costly calls storage.getnow seem to be cached.

There are two problems.

, fooSubject, foo$ , , .

foo$ Subject Setting, subscribe(...) next(...)?

-, .

storage.get storage.set, promises?

+4
2

, AnonymousSubject ( Subject.create(...) factory). destination source, .

class FooSharedSubject extends AnonymousSubject {
    constructor() {
        const subject = new BehaviorSubject('');

        const observable = subject.asObservable()
        .mergeMap((value) => promisedStorage.get('foo'))
        .publishReplay(1)
        .refCount();

        super(subject, observable);
    }

    next(value): void {
        promisedStorage.set('foo', value)).then(
            () => this.destination.next(value),
            () => this.destination.error(value)
        );
    }
}
+3

, , . , , , , this.foo$ .

ReplaySubject storage.get('foo') storage.set('foo', val); .

: http://plnkr.co/edit/pxjRQr6Q6Q7LzYb1oode?p=preview

, .

class Setting {

  constructor() {
    var storage = new Storage();

    this.fooSubject = new ReplaySubject(1);
    this.fooSubject.subscribe((val) => {
      storage.set('foo', val);
    });
  }

  get observable() {
    return this.fooSubject.asObservable();
  };

  store(val) {
    this.fooSubject.next(val);
  }
}

, Subject .asObservable() .next() store() . :

let settings = new Setting();

settings.store('Hello');

settings.observable.subscribe(val => console.log(val));
settings.store('Hello 2');
settings.store('Hello 3');

settings.observable.subscribe(val => console.log(val));
settings.store('Hello 4');

:

Hello
Hello 2
Hello 3
Hello 3
Hello 4
Hello 4

, ReplaySubject . setting.fooSubject.next(newFoo) ReplaySubject, storage.set('foo', val);.

. , , . JavaScript , storage.get('foo') , , , - -.

+3

Source: https://habr.com/ru/post/1656289/


All Articles