web-dev-qa-db-ja.com

angular 2でストア(ngrx)を使用する利点は何ですか?

angular 1.x.xプロジェクトに取り組んでおり、コードをangular 2にアップグレードすることを考えています。

現在、私のプロジェクトには、データを処理するための多くのサービス(工場)があり、ほとんどデータをjs配列(キャッシュとストレージの両方)に保持し、配列を処理するためにアンダースコアを使用してこれらのデータを処理します.

Ngrxを使用したangular2の多くの例が見つかりました。

ストアを使用してデータサービスを使用してデータを処理する利点は何ですか?

複数のデータ型(在庫、注文、顧客...)がある場合、アプリに複数のストアが必要ですか?

これらのような複数のデータ型を処理するためにアプリをどのように構成(設計)できますか?

51
Vu Quyet

あなたの質問は主に意見に基づいていますが、なぜngrxが良い選択であるかについていくつかのアイデアを提供できます。すべてのアプリケーションの状態を1つのオブジェクト(単一の状態ツリー)に保持するのは得策ではないと言われていますが。しかし、私の意見ではあなたの状態は関係なくそこにあるでしょう。ストアを使用すると、すべてが1か所になり、突然変異は明示的に追跡され、全体にわたって散らばり、コンポーネントによってローカルに維持されます。また、アプリケーション内のストアから特定のプロパティを選択するため、関心のあるデータのみを選択できます。次に、常に配列を返し、Observablesを使用してレデューサーに不変性を取り入れる場合、ChangeDetectionStrategy OnPushを使用できます。 OnPushを使用すると、パフォーマンスが向上します。公式のAngular docs から取った次の図を見てみましょう。

enter image description here

ご覧のとおり、Angularアプリはコンポーネントアーキテクチャを使用して構築され、コンポーネントツリーが作成されます。コンポーネントのOnPushは、入力属性が変更された場合のみ、検出が開始されます。たとえば、Child BOnPushおよびChild ADefaultであり、Child AChild Bの変更検出器は、入力属性が変更されていないためトリガーされません。ただし、Child BChild Aにはデフォルトの変更検出機能があるため、再レンダリングされます。

パフォーマンスと単一の状態ツリーについてはとても重要です。ストアのもう1つの利点は、コードと状態の変更について実際に推論できることです。したがって、ほとんどのAngular 1.xアプリの現実はscope soupです。これは、- ブログ投稿 Lukas Ruebbelke:

enter image description here

写真はそれがかなり良いことを示しています。別の 記事 Tero Parviainenから、彼がどのように彼のAngularアプリを禁止することで改善したかについて話しますng-controller。すべてがスコープスープに関連し、絶えず変化する状態を管理することは困難です。 redux動機は、次のことを言っています こちらを参照

モデルが別のモデルを更新できる場合、ビューはモデルを更新でき、別のモデルを更新します。これにより、別のビューが更新される可能性があります。ある時点で、いつ、なぜ、どのように状態を制御できなくなったため、アプリで何が起こるか理解できなくなります。システムが不透明で非決定的である場合、バグを再現したり、新しい機能を追加したりすることは困難です。

Ngrx/storeを使用すると、アプリで明確なデータフローが得られるため、実際にこの問題を回避できます。

Ngrxはreduxに非常に触発されているため、同じ 主な原則 が適用されると言います。

  • 単一の真実の源
  • 状態は読み取り専用です
  • 変更は純粋な関数で行われます

だから、私の意見では、最大の利点は、アクションをディスパッチし、アクションが常に1つのスポットにつながるので、ユーザーの相互作用と状態変化の理由を簡単に追跡できることです。一方、プレーンモデルでは、すべての参照を見つけていつ。

Ngrx/storeを使用すると、 devtools を使用して、状態コンテナのデバッグを確認し、変更を元に戻すこともできます。時間旅行は、リデュースの主な理由の1つであり、単純な古いモデルを使用している場合、それは非常に困難です。

すでに述べた@muetzerichとしてのテスト容易性は、ngrx/storeを使用することの利点でもあります。レデューサーは純粋な関数であり、入力を受け取り、出力を返すだけで、関数の外部のプロパティに依存せず、副作用がないため、テストが簡単です。 http呼び出しなど.

一番下の行にジャンプするには、これらのことを行うためにngrx/storeを使用する必要はないと言いますが、共通のパターンを提供してニースのメリットをもたらす制限(上記の3つの原則)に縛られます。

ご質問へ:

複数のデータタイプ(在庫、注文、顧客...)がある場合、アプリに複数のストアが必要ですか?

いいえ、複数のストアを使用することはお勧めしません。

これらのような複数のデータ型を処理するようにアプリを構成(設計)するにはどうすればよいですか?

たぶんこれ ブログ投稿 Tero Parviainenによって、あなたの店のデザイン方法を理解するのに役立ちます。彼は、サンプルアプリのアプリケーション状態ツリーを設計する方法を説明します。

70
LordTribual

そこにあるストアを使用する利点についての良い説明 documentation

集中化された不変の状態

関連するアプリケーションの状態はすべて1つの場所に存在します。これにより、エラー発生時の状態のスナップショットが重要な洞察を提供し、問題を簡単に再現できるため、問題の追跡が容易になります。これにより、ストアアプリケーションのコンテキストでは元に戻す/やり直しなどの難しい問題が発生し、強力なツールが有効になります。

パフォーマンス

状態はアプリケーションの最上部に集中化されているため、データの更新はストアのスライスに依存してコンポーネント全体に流れます。 Angular 2は、このようなデータフローの配置を最適化するために構築され、コンポーネントが新しい値を発行していないObservablesに依存している場合、変更検出を無効にできます。コンポーネントの大部分。

テスト容易性

すべての状態の更新は、純粋な関数であるリデューサーで処理されます。純粋な関数は、単純に入力され、出力に対してアサートされるため、テストが非常に簡単です。これにより、複雑でエラーが発生しやすいモック、スパイ、またはその他のトリックを使用せずに、アプリケーションの最も重要な側面をテストできます。

複数の店舗?

IMOは1つのストアを使用し、データ型をストアのプロパティとして追加します。

8
muetzerich

ngrx.storeは、適切に設計されたコンポーネント/サービスが行うことと、追加の利点を提供します。これまでのところ、私はこれがどのように組み合わされるかを早くから調べていますが、これは私が見つけたものです:

サービスやコンポーネントでメンテナンスできない混乱を招くのは本当に簡単です。カスケードアクション、複雑なデータインタラクション、およびリモートロケーションへの呼び出しがある場合、ngrxのaction-reducer-store配置とほぼ同じサービスを構築することになります。小さな純粋な関数、オブザーバブルなど。ngrxにはすでにそれがあります。なぜそれを使用し、それが表す思考とパターンから利益を得ないのか。

小さいテスト可能な機能で考えることを力/奨励する場合。中程度に複雑なコンポーネントのレデューサーまたは複数のレデューサーをレイアウトすると、時間を消費する多くの落とし穴を取り除く規律が実施されます。コールバックキューから生じる準マルチスレッドの競合状態を追跡するような時間を飲み込むことはありません。レデューサーでこれが発生する可能性があると確信していますが、デバッグのために呼び出しシーケンスと状態へのアクセスを簡素化します。

Angular2パターンが簡単になります。表示ロジックを備えたテンプレート、テンプレートが必要とするすべての断片の集合場所としてのコンポーネント。サービスは、単純にリモート呼び出しを行うか、どこから来たデータのioを処理するため、よりシンプルになります。次に、状態を維持および変更するためのアクションとリデューサー。これにより、他のすべての部分が新しい状態に応答します。コンポーネント/サービスパターンでは、どちらかが大きく複雑になり始め、その副作用がデバッグするのが非常に難しくなることがわかりました。私のサービスは最終的に状態を保存し、データ入出力を行っていました。

オブザーバブル。すべてがrxjs.storeで観察可能であり、それがレスポンシブアプリの基盤です。アプリの状態をオブザーバブルとして構造化することは、少し難解であるか非常に単純ではない場合がありますが、それを理解してそれをうまく行うことは、将来的に大きな利益をもたらします。

私が見ることができる唯一のマイナスは、減速機が非常に急速に非常に大きくなることです。同じコードが異なる名前で繰り返され、繰り返される状況がたくさんあるようです。私の脳は「パラメータを持つ関数」を叫んでいますが、それはうまくいきません。一方、これはアプリの構造と状態がすべて詳細に表現される場所であるため、そこには多くの制約があります。そして、必然的に何か問題が発生した場合、問題の原因として純粋な機能があると、追跡と修正が容易になります。

6
Derek Kite