3

すべてがうまくいけば、JSON としてコード化された単一の配列を含む HTTP 応答を受け取ります。
この配列を取得し、いくつかの項目を除外して、通過する項目をイベントとして処理したいと考えています。

私がこれまでに行っていることは次のとおりです。

    return this._http.get(url)
        .map((res:Response) => res.json())
        .map((data:any) => {
            if (!Array.isArray(data) || data.length == 0) {
                throw new Error("No items returned, URL: " + url);
            }
            let projects = <ProjectModel[]>service.fromJSONarray(data, this._http);
            return Observable.from(projects)
                .filter((project: ProjectModel) => project.parentProject == null)
                .subscribe(project -> ...)
        })

しかし、私は入れ子が好きではありません。これを行う方法があると思います:

    return this._http.get(url)
        .map((res:Response) => res.json())
        .map((data:any) => {
            ...
            let projects = <ProjectModel[]>service.fromJSONarray(data, this._http);
            ???
        })
        .filter((project: ProjectModel) => project.parentProject == null)
        .subscribe(project -> ...)

それを達成する方法は?

4

2 に答える 2

7

RxJS 5を使用していると仮定するとconcatAll()、ネストされた配列をフラット化するための文書化されていない機能を使用するconcatAll()と、高次のオブザーバブルで動作するように作られていますが、さらに簡単な方法があります。

let data = '[{"id":1},{"id":2},{"id":3},{"id":4}]';

Observable.of(data)
    .map(JSON.parse)
    .concatAll() // each object is emitted separately
    .map(p => p) // transform to ProjectModel
    .filter(p => true) // filter whatever you want
    .subscribe(v => console.log(v));

service.fromJSONarray単一のインスタンスのみを返す場合は、ProjectModelこのように単純になります。service.fromJSONarray配列を返す必要がある場合は、 と の間map(JSON.parse)に配置しますconcatAll()。このデモはコンソールに出力されます:

{ id: 1 }
{ id: 2 }
{ id: 3 }
{ id: 4 }

ただし、他のオブザーバブルを発行するオブザーバブルを返す場合は、service.fromJSONarray使用する必要がある追加の HTTP リクエストを実行する必要があるため、またはアイテムの同じ順序を維持するかどうかに応じて、次のようになりますconcatMap()flatMap()

let data = '[{"id":1},{"id":2},{"id":3},{"id":4}]';

function fromJSONarray(arr) {
    return Observable.from(arr)
        .flatMap(p => Observable.of(p));
}

Observable.of(data)
    .map(d => fromJSONarray(JSON.parse(d)))
    .concatAll()
    .map(p => p) // transform to ProjectModel
    .subscribe(v => console.log(v));

結果は同じです。

同様の質問:

于 2016-12-12T08:18:44.400 に答える
1

Observable の配列にマッピングするときはいつでも、次のように考える必要がありますflatMap

あなたの例では、次のようになります。

return this._http.get(url)
    .map((res:Response) => res.json())
    .flatMap((data:any) => {
        if (!Array.isArray(data) || data.length == 0) {
            throw new Error("No items returned, URL: " + url);
        }
        let projects = <ProjectModel[]>service.fromJSONarray(data, this._http);
        return Observable.from(projects);
    })
    .filter((project: ProjectModel) => project.parentProject == null)
    //...etc

または、もっと単純に

Observable
  .range(0, 2)
  .flatMap(() => Observable.from([1, 2, 3]))
  .filter((foo) => foo !== 1)
  .subscribe((res) => console.log(res));

// 2
// 2
// 3
// 3
于 2016-12-12T00:10:03.367 に答える