Angular の
状態管理 により、アプリケーションのすべての部分でデータが一貫して効率的に共有されることが保証されます。各コンポーネントが独自のデータを管理する代わりに、中央ストアが状態を保持します。
この一元化により、データが変更されると、すべてのコンポーネントが更新された状態を自動的に反映し、一貫した動作とよりシンプルなコードが実現されます。また、データ フローが単一の信頼できる情報源から管理されるため、アプリの保守と拡張が容易になります。
この記事では、簡単なショッピング カート アプリケーションを構築することで、NgRx を使用して Angular で状態管理を実装する方法を検討します。 ストア、アクション、リデューサー、セレクター、、エフェクト などの NgRx の中心的な概念を取り上げ、これらの部分がどのように連携してアプリケーションの状態を管理するかを示します。効果的に。
Angular のState は、ショッピング カートの内容など、アプリが管理および表示する必要があるデータを指します。
状態管理が必要な理由
1.一貫性: すべてのコンポーネントにわたってデータが均一であることを保証します。 1 か所のデータが変更されると、中央ストアが関連するすべてのコンポーネントを自動的に更新し、不整合を防ぎます。
2.簡素化されたデータ フロー: コンポーネント間でデータを手動で渡す代わりに、状態管理により、すべてのコンポーネントが中央ストアから直接データにアクセスしたり更新したりできるため、アプリのデータ フローの管理と理解が容易になります。
3.より簡単なメンテナンスとスケーラビリティ: データ管理を一元化することで、状態管理によりコードの重複と複雑さが軽減されます。これにより、アプリの保守、デバッグ、拡張が容易になります。
4.パフォーマンスの最適化: 状態管理ソリューションには、アプリケーション全体を再レンダリングするのではなく、状態の変化に対応する必要があるコンポーネントのみを選択的に更新するなど、パフォーマンスを最適化するためのツールが付属していることがよくあります。
NgRx の仕組み
NgRx は、アプリケーションの状態を予測可能な方法で管理および維持するのに役立つ Angular の状態管理ライブラリです。
1.コンポーネント
コンポーネントは、ユーザーがアプリと対話する場所です。ショッピング カートに商品を追加するボタンである可能性があります。
コンポーネントとサービスは分離されており、相互に直接通信することはありません。代わりに サービス は エフェクト 内で使用されるため、従来の Angular アプリとは異なるアプリケーション構造が作成されます。
2.アクション
アクションは何が起こったかを説明し、必要なペイロード (データ) を含みます。
3.レデューサー
アクションに基づいて状態を更新します。
4.ストア
ストアは、アプリケーションの状態全体を保持する一元的な場所です。
5.セレクター
ストアからコンポーネントのデータを抽出します。
6.効果
エフェクトは、API 呼び出しなど、リデューサーに属さないロジックを処理する場所です。
7.サービス
サービスは実際のビジネス ロジックまたは API 呼び出しを実行します。エフェクトは多くの場合、サーバーからのデータの取得などのタスクを実行するためにサービスを使用します。
NgRx を使用する場合
アプリの複雑さが正当な場合は NgRx を使用しますが、単純なアプリの場合は、より単純な状態管理方法を使用してください。コンポーネント間のコンポーネント間の Angular の services、signals、および @Input/@Output バインディングは、通常、それほど複雑でないアプリケーションの状態を管理するのに十分です。
例: NgRx を使用してカートに追加機能を構築する
1.新しい Angular プロジェクトを作成します:
ng new shopping-cart
2. NGRX とエフェクトをインストールします
NGRX とエフェクトをインストールするには、ターミナルで次のコマンドを実行します:
ng add @ngrx/store@latest ng add @ngrx/effects
3.製品モデルを定義します
src/app ディレクトリ内に、product.model.ts
製品の構造を表す Product インターフェイスを定義します。
export interface Product { id: string; name: string; price: number; quantity: number; }
4.状態管理のセットアップ
ステップ 1: src/app ディレクトリ内に state フォルダーを作成します
ステップ 2: カート アクションを定義する
state フォルダーに cart.actions.ts を作成します。
import { createActionGroup, emptyProps, props } from '@ngrx/store'; import { Product } from '../product.model'; export const CartActions = createActionGroup({ source: 'Cart', events: { 'Add Product': props(), 'Remove Product': props(), 'Update Quantity': props(), 'Load Products': emptyProps, }, }); export const CartApiActions = createActionGroup({ source: 'Cart API', events: { 'Load Products Success': props(), 'Load Products Failure': props(), }, });
ステップ 3: レデューサーを作成する
state フォルダーに cart.reducer.ts を作成します。
import { createReducer, on } from '@ngrx/store'; import { Product } from '../product.model'; import { CartActions, CartApiActions } from './cart.actions'; // Initial state for products and cart export const initialProductsState: ReadonlyArray<product> = []; export const initialCartState: ReadonlyArray<product> = []; // Reducer for products (fetched from API) export const productsReducer = createReducer( initialProductsState, on(CartApiActions.loadProductsSuccess, (_state, { products }) => products) ); // Reducer for cart (initially empty) export const cartReducer = createReducer( initialCartState, on(CartActions.addProduct, (state, { product }) => { const existingProduct = state.find(p => p.id === product.id); if (existingProduct) { return state.map(p => p.id === product.id ? { ...p, quantity: p.quantity + product.quantity } : p ); } return [...state, product]; }), on(CartActions.removeProduct, (state, { productId }) => state.filter(p => p.id !== productId) ), on(CartActions.updateQuantity, (state, { productId, quantity }) => state.map(p => p.id === productId ? { ...p, quantity } : p ) ) ); </product></product>
ステップ 4: セレクターを作成する
state フォルダーに、cart.selectors.ts
を作成します。
import { createSelector, createFeatureSelector } from '@ngrx/store'; import { Product } from '../product.model'; export const selectProducts = createFeatureSelector<readonlyarray>>('products'); export const selectCart = createFeatureSelector<readonlyarray>>('cart'); export const selectCartTotal = createSelector(selectCart, (cart) => cart.reduce((total, product) => total + product.price * product.quantity, 0) ); </readonlyarray></readonlyarray>
Step 5: Create Effects
Create a new file cart.effects.ts in the state folder that listens for the Load Products action, uses the service to fetch products, and dispatches either a success or failure action.
import { Injectable } from '@angular/core'; import { Actions, createEffect, ofType } from '@ngrx/effects'; import { ProductService } from '../product.service'; import { CartActions, CartApiActions } from './cart.actions'; import { catchError, map, mergeMap } from 'rxjs/operators'; import { of } from 'rxjs'; @Injectable() export class CartEffects { loadProducts$ = createEffect(() => this.actions$.pipe( ofType(CartActions.loadProducts), mergeMap(() => this.productService.getProducts().pipe( map(products => CartApiActions.loadProductsSuccess({ products })), catchError(error => of(CartApiActions.loadProductsFailure({ error }))) ) ) ) ); constructor( private actions$: Actions, private productService: ProductService ) {} }
5. Connect the State Management to Your App
In a file called app.config.ts, set up configurations for providing the store and effects to the application.
import { ApplicationConfig } from '@angular/core'; import { provideStore } from '@ngrx/store'; import { provideHttpClient } from '@angular/common/http'; import { cartReducer, productsReducer } from './state/cart.reducer'; import { provideEffects } from '@ngrx/effects'; import { CartEffects } from './state/cart.effects'; export const appConfig: ApplicationConfig = { providers: [ provideStore({ products: productsReducer, cart: cartReducer }), provideHttpClient(), provideEffects([CartEffects]) ], };
6. Create a Service to Fetch Products
In the src/app directory create product.service.ts to implement the service to fetch products
import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { Product } from './product.model'; @Injectable({ providedIn: 'root' }) export class ProductService { getProducts(): Observable<array>> { return of([ { id: '1', name: 'Product 1', price: 10, quantity: 1 }, { id: '2', name: 'Product 2', price: 20, quantity: 1 }, ]); } } </array>
7. Create the Product List Component
Run the following command to generate the component: ng generate component product-list
This component displays the list of products and allows adding them to the cart.
Modify the product-list.component.ts file:
import { Component, OnInit } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { Product } from '../product.model'; import { selectProducts } from '../state/cart.selectors'; import { CartActions } from '../state/cart.actions'; @Component({ selector: 'app-product-list', standalone: true, templateUrl: './product-list.component.html', styleUrls: ['./product-list.component.css'], imports: [CommonModule], }) export class ProductListComponent implements OnInit { products$!: Observable<readonlyarray>>; constructor(private store: Store) { } ngOnInit(): void { this.store.dispatch(CartActions.loadProducts()); // Dispatch load products action this.products$ = this.store.select(selectProducts); // Select products from the store } onAddToCart(product: Product) { this.store.dispatch(CartActions.addProduct({ product })); } } </readonlyarray>
Modify the product-list.component.html file:
<div async as products> <div class="product-item" product of products> <p>{{product.name}}</p> <span>{{product.price | currency}}</span> <button data-test="add-button">Add to Cart</button> </div> </div>
8. Create the Shopping Cart Component
Run the following command to generate the component: ng generate component shopping-cart
This component displays the products in the cart and allows updating the quantity or removing items from the cart.
Modify the shopping-cart.component.ts file:
import { Component, OnInit } from '@angular/core'; import { CommonModule } from '@angular/common'; import { Store } from '@ngrx/store'; import { Observable } from 'rxjs'; import { Product } from '../product.model'; import { selectCart, selectCartTotal } from '../state/cart.selectors'; import { CartActions } from '../state/cart.actions'; @Component({ selector: 'app-shopping-cart', standalone: true, imports: [CommonModule], templateUrl: './shopping-cart.component.html', styleUrls: ['./shopping-cart.component.css'], }) export class ShoppingCartComponent implements OnInit { cart$: Observable<readonlyarray>>; cartTotal$: Observable<number>; constructor(private store: Store) { this.cart$ = this.store.select(selectCart); this.cartTotal$ = this.store.select(selectCartTotal); } ngOnInit(): void {} onRemoveFromCart(productId: string) { this.store.dispatch(CartActions.removeProduct({ productId })); } onQuantityChange(event: Event, productId: string) { const inputElement = event.target as HTMLInputElement; let quantity = parseInt(inputElement.value, 10); this.store.dispatch(CartActions.updateQuantity({ productId, quantity })); } } </number></readonlyarray>
Modify the shopping-cart.component.html file:
<div async as cart> <div class="cart-item" product of cart> <p>{{product.name}}</p> <span>{{product.price | currency}}</span> <input type="number" product.id> <button data-test="remove-button">Remove</button> </div> <div class="total"> Total: {{cartTotal$ | async | currency}} </div> </div>
Modify the shopping-cart.component.css file:
.cart-item { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; } .cart-item p { margin: 0; font-size: 16px; } .cart-item input { width: 50px; text-align: center; } .total { font-weight: bold; margin-top: 20px; }
9. Put Everything Together in the App Component
This component will display the product list and the shopping cart
Modify the app.component.ts file:
import { Component } from '@angular/core'; import { CommonModule } from '@angular/common'; import { ProductListComponent } from './product-list/product-list.component'; import { ShoppingCartComponent } from './shopping-cart/shopping-cart.component'; import { NgIf } from '@angular/common'; @Component({ selector: 'app-root', standalone: true, templateUrl: './app.component.html', imports: [CommonModule, ProductListComponent, ShoppingCartComponent, NgIf], }) export class AppComponent {}
Modify the app.component.html file:
<!-- app.component.html --> <h2 id="Products">Products</h2> <app-product-list></app-product-list> <h2 id="Shopping-Cart">Shopping Cart</h2> <app-shopping-cart></app-shopping-cart>
10. Running the Application
Finally, run your application using ng serve.
Now, you can add products to your cart, remove them, or update their quantities.
Conclusion
In this article, we built a simple shopping cart application to demonstrate the core concepts of NgRx, such as the Store, Actions, Reducers, Selectors, and Effects. This example serves as a foundation for understanding how NgRx works and how it can be applied to more complex applications.
As your Angular projects grow in complexity, leveraging NgRx for state management will help you maintain consistency across your application, reduce the likelihood of bugs, and make your codebase easier to maintain.
To get the code for the above project, click the link below:
https://github.com/anthony-kigotho/shopping-cart
以上がNgRx を使用して Angular 状態管理をマスターするの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

JavaScriptフレームワークのパワーは、開発を簡素化し、ユーザーエクスペリエンスとアプリケーションのパフォーマンスを向上させることにあります。フレームワークを選択するときは、次のことを検討してください。1。プロジェクトのサイズと複雑さ、2。チームエクスペリエンス、3。エコシステムとコミュニティサポート。

はじめに私はあなたがそれを奇妙に思うかもしれないことを知っています、JavaScript、C、およびブラウザは正確に何をしなければなりませんか?彼らは無関係であるように見えますが、実際、彼らは現代のウェブ開発において非常に重要な役割を果たしています。今日は、これら3つの間の密接なつながりについて説明します。この記事を通して、JavaScriptがブラウザでどのように実行されるか、ブラウザエンジンでのCの役割、およびそれらが協力してWebページのレンダリングと相互作用を駆動する方法を学びます。私たちは皆、JavaScriptとブラウザの関係を知っています。 JavaScriptは、フロントエンド開発のコア言語です。ブラウザで直接実行され、Webページが鮮明で興味深いものになります。なぜJavascrを疑問に思ったことがありますか

node.jsは、主にストリームのおかげで、効率的なI/Oで優れています。 ストリームはデータを段階的に処理し、メモリの過負荷を回避します。大きなファイル、ネットワークタスク、リアルタイムアプリケーションの場合。ストリームとTypeScriptのタイプの安全性を組み合わせることで、パワーが作成されます

PythonとJavaScriptのパフォーマンスと効率の違いは、主に以下に反映されています。1)解釈された言語として、Pythonはゆっくりと実行されますが、開発効率が高く、迅速なプロトタイプ開発に適しています。 2)JavaScriptはブラウザ内の単一のスレッドに限定されていますが、マルチスレッドおよび非同期I/Oを使用してnode.jsのパフォーマンスを改善でき、両方とも実際のプロジェクトで利点があります。

JavaScriptは1995年に発信され、Brandon Ikeによって作成され、言語をCに実現しました。 2。JavaScriptのメモリ管理とパフォーマンスの最適化は、C言語に依存しています。 3. C言語のクロスプラットフォーム機能は、さまざまなオペレーティングシステムでJavaScriptを効率的に実行するのに役立ちます。

JavaScriptはブラウザとnode.js環境で実行され、JavaScriptエンジンに依存してコードを解析および実行します。 1)解析段階で抽象的構文ツリー(AST)を生成します。 2)ASTをコンパイル段階のバイトコードまたはマシンコードに変換します。 3)実行段階でコンパイルされたコードを実行します。

PythonとJavaScriptの将来の傾向には、1。Pythonが科学コンピューティングの分野での位置を統合し、AI、2。JavaScriptはWebテクノロジーの開発を促進します。どちらもそれぞれのフィールドでアプリケーションシナリオを拡大し続け、パフォーマンスをより多くのブレークスルーを行います。

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。


ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

MantisBT
Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

SublimeText3 中国語版
中国語版、とても使いやすい

SublimeText3 Linux 新バージョン
SublimeText3 Linux 最新バージョン

SecLists
SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

ホットトピック









