Как преобразовать Observable ‹Product []› в Observable ‹Product› [] без подписки?

В моем текущем проекте angular у меня есть служба, которая возвращает Observable ‹Product []›. Я хотел бы преобразовать этот поток в массив Observables одного продукта. Я хочу добиться этого с помощью операторов канала, не подписываясь на исходный поток.

От Observable of ‹entity []› к массиву Observable of entity


person Narasimhan    schedule 27.06.2020    source источник
comment
Я не думаю, что это возможно с операторами канала, потому что метод канала принимает только операторы, которые генерируют одно наблюдаемое. Возможно, вы сможете сделать это, создав массив BehaviorSubjects и отправив туда результаты.   -  person ShamPooSham    schedule 27.06.2020
comment
Спасибо @ShamPooSham. Я попробую это.   -  person Narasimhan    schedule 28.06.2020
comment
Честно говоря, я не уверен, чего вы хотите этим добиться. Из вашего другого комментария похоже, что вы хотите прокрутить результат в своем шаблоне с помощью *ngFor и async. Это не невозможно достичь с Observable<etntity[]>. Может быть, ваш вопрос должен быть об этом   -  person ShamPooSham    schedule 28.06.2020
comment
Мне кажется, что мое решение довольно уродливое и усложняет понимание кода.   -  person ShamPooSham    schedule 28.06.2020
comment
Если я перебираю простой div, этого не потребуется. На самом деле компонент, с которым я зацикливаюсь, * ngFor ожидает наблюдаемого единственного объекта. ‹Product-catalog-item [product] = productItem› ‹/product-catalog-item›.   -  person Narasimhan    schedule 28.06.2020


Ответы (1)


Когда вы используете pipe для наблюдаемого объекта, вы всегда получаете новый наблюдаемый объект, а не массив. Вы можете получить доступ к Product[] и сопоставить его с (Observable<Product>)[] без каких-либо проблем, но результат все равно будет заключен в другой наблюдаемый объект:

import { of } from 'rxjs';
import { map } from 'rxjs/operators';

interface Product {
    id: number;
}

const products: Observable<Product[]> = of([
    { id: 1 },
    { id: 2 },
    { id: 3 },
]);

products
    .pipe(map(ps => ps.map((p) => of(p))))
    .subscribe((observables: Observable<Product>[]) => {
        // In here you can access the array of observables:
        console.log(observables);
    })

Вместо подписки на наблюдаемое вы также можете tap в pipe, чтобы получить доступ к результату map(), но результат по-прежнему будет доступен только из наблюдаемого контекста:

// ...
import { map, tap } from 'rxjs/operators';
// ...

const x = products
    .pipe(
        map(ps => ps.map((p) => of(p))),
        tap((observables: Observable<Product>[]) => {
            // In here you can also access the array of observables:
            console.log(observables);
        }),
    );

Но x все еще наблюдается:

const x: Observable<Observable<Product>[]>

или, что то же самое, но может быть немного более понятным:

const x: Observable<Array<Observable<Product>>>
person JJWesterkamp    schedule 27.06.2020
comment
Одна вещь, которая может помочь понять, - это то, что в контексте наблюдаемых неизвестно, сколько записей имеет массив событий. Массив не ограничен и поэтому не может быть динамически разделен на несколько переменных. Попарно делает то, что хочет, но оператор разбивается только на две отдельные части. - person Jonathan Stellwag; 27.06.2020
comment
Спасибо, Джеффри, в этом есть смысл. Но невозможно перебрать наблюдаемые из наблюдаемых в шаблоне с помощью async pipe. - person Narasimhan; 28.06.2020