6

私は (@ngrx/store を使用して) Redux を使用する Angular 2 アプリで、ストアを次のようにモデル化しました。

{

  modelA: {
    ids: [1, 2],
    entities: { 1: { name: "name modelA 1" },
                2: { name: "name modelA 2" }
              }
  },

  modelB: {
    ids: [5, 8],
    entities: { 5: { name: "name modelB 5" },
                8: { name: "name modelA 8" },
                9: { name: "name modelA 9" }
              }
  } 

}

基本的に、モデル A とモデル B の 2 種類のオブジェクトがあります。これで今のところ問題ありません。しかし、モデル A に多くのモデル B (1 対多) があるようなものを表す、それらの間の関係を記述する最良の方法を見つけることができません。このようなことはできますか?

modelAmodelB: {
  entities: {
    1: [5],
    2: [8, 9]
  }
}

これはストアのルートにあり、「modelA」の子ではありません。これは機能するかもしれませんが、@ngrx/store メソッドを使用して、特定の modelA から modelB を「クエリ」するにはどうすればよいでしょうか? グローバルな状態を読み取り、modelAmodelB から部分的な状態を返すセレクター関数を作成すると、関数を作成するときに残りの状態にアクセスできないためです。例:

compose(getModelAEntities(number[]), getModelAModelBRelations(modelA_id: number), getModelAModelBState() );

Observable.combineLast を使用してこれをクエリできます

Observable
.combineLatest(
  this.store.select('contentContents'),
  this.store.select('contents'),
  (relations: any, contents: any) => {
    return relations.entities[1].map( id => {
      return contents.entities[id]
    })
  }
).subscribe( data => {
  console.log(data);
})

しかし、これが正しいかどうかはわかりません: modelA エンティティ オブジェクトを変更するたびに (たとえば、新しいオブジェクトを追加する)、subscribe() が呼び出されますが、modelA エンティティもその modelB も変更されていないため、出力は同じです。関連オブジェクト。

PS:この方法でクエリを実行できます

export const getModelAModelBs = (id) => {
  return state => 
    state.select( (s: any) => [s.modelAModelB.entities[id], s.modelB.entities])
    .distinctUntilChanged( (prev, next) => {

      const new_m = (next[0] || []).map( id => {
        return next[1][id];
      });

      const old_m = (next[0] || []).map( id => {
        return prev[1][id];
      });

      return prev[0] === next[0] && (JSON.stringify(new_m) === JSON.stringify(old_m))
    })
    .map( ([ids = [], modelBs]) => ids.map( id => modelBs[id]) );
};

//use the selector
this.store.let(getModelAModelBs(1)).subscribe( data => {
  console.log(data)
})

しかし、これが最善のアプローチであるかどうかはわかりません。

4

1 に答える 1