Observable Array of Observables - Как реализовать в RxJS? - PullRequest
0 голосов
/ 24 апреля 2019

Я впервые изучаю RxJS, поэтому прошу прощения, если этот вопрос основан на ложных предположениях.

Скажем, например, что в моем приложении Angular есть FooService, который возвращает Array<Foo>. Элементы могут быть добавлены и удалены из списка произвольно. Поэтому я обертываю свой массив Foos в наблюдаемую RxJS; FooService теперь возвращает BehavioralSubject<Array<Foo>>. Теперь я могу использовать AsyncPipe от Angular для автоматической перерисовки необходимых компонентов при каждом обновлении BehavioralSubject. Пока что это тривиальный RxJS 101.

Но в моем приложении не только Массив Foos может получать обновления, но и каждый отдельный Foo может получать обновления, не затрагивая Массив. Как мне это спроектировать? Должен ли я обернуть каждый отдельный Foo в Observable, чтобы мой FooService возвращал BehavioralSubject<Array<BehavioralSubject<Foo>>>? Это кажется грязным. Продолжаю ли я возвращать BehavioralSubject<Array<Foo>> и перерисовывать весь компонент Array каждый раз при обновлении Foo? Это тесно связывает обновления Foo с обновлениями Array, не позволяя мне повторно использовать мой компонент Foo в других частях приложения.

Какой лучший способ сделать это в RxJS? Как мне (фактически) реализовать (концептуальный) Наблюдаемый Массив Наблюдаемых?

1 Ответ

4 голосов
/ 24 апреля 2019

Но в моем приложении не только Массив Foos может получать обновления, но и каждый отдельный Foo может получать обновления, не затрагивая Массив.

Это не имеет смысла для меня. Если у вас есть массив, содержащий foos, и один из foos изменяется, этот массив по своей сути изменяется.

Если вы используете директиву ngFor, распространение изменений в вашем шаблоне будет оптимизировано, поэтому вам не придется беспокоиться о повышенном DOM-подъеме в большинстве случаев использования: https://angular.io/api/common/NgForOf#change-propagation

Если вам нужно больше контроля, проверьте это: https://angular.io/guide/template-syntax#ngfor-with-trackby

Теперь, к вашим услугам, вы можете сделать это:

private foos = new BehaviorSubject<Foo[]>([]);

Затем создайте функцию, которая возвращает Observable для использования в вашем шаблоне:

get() { 
    return this.foos.asObservable(); 
}

Затем вы добавляете логику, чтобы изменить foos так, как вам нравится, например, добавьте foo:

add(foo: Foo) {
    let arr = this.foos.getValue();
    arr.push(foo);
    this.foos.next(arr);
}

Поменяйте foo:

change(index: number, foo: Foo) {
    let arr = this.foos.getValue();
    arr[index] = foo;
    this.foos.next(arr);
}

Затем в вашем компоненте используйте fooService.get() | async

...