برنامه نویسی

زمان و چرا باید از REDUX NgRx در Angular استفاده کرد

در مقاله قبلی، در مورد مدیریت وضعیت در Angular با استفاده از Services نوشتم، اما وقتی برنامه افزایش می یابد و نیاز به ردیابی و مدیریت یک وضعیت بزرگ دارد، کمی پیچیده می شود و مدیریت آن آسان نیست. به عنوان مثال، وقتی اجزای زیادی داریم که باید به آن تغییرات در حالت واکنش نشان دهند.

در ابتدا، استفاده از یک سرویس با موضوع رفتار آسان است، اما گاهی اوقات ما با مشکلات یا عوارض جانبی مواجه می شویم که تشخیص محل وقوع مشکل را دشوار می کند.

در برنامه‌هایمان، ممکن است چند نوع حالت را مدیریت کنیم: گاهی اوقات در پشتیبان و از یک API، در وضعیت URL مانند http://myapp.com/users?id=2، یا در یک مؤلفه واحد. بنابراین، چه زمانی واقعا نیاز به استفاده از NgRx دارم؟ 🤔

آیا نیاز به استفاده از NgRx دارید؟

خوب، NgRx یک ابزار عالی است، اما من از آن برای همه برنامه هایم استفاده نمی کنم. چرا؟ قبل از شروع با NgRx، چند سوال از خودم می‌پرسم:

  • آیا برنامه من کوچک و یک MVP است؟

  • آیا من به یک حالت نیاز دارم و اجزای من نیازی به واکنش به سایر تغییرات حالت ندارند؟

  • آیا هم تیمی های من RxJS و Redux را نیز می شناسند؟

اگر پاسخ شما مثبت است، پس نیازی به NgRx ندارید. زیرا NgRx به دانش خوب RxJS نیاز دارد و شامل نوشتن کد دیگ بخار است. بنابراین، اگر روی چیزی کوچک کار می‌کنید یا MVP خود را تحویل می‌دهید، سعی کنید با استفاده از Angular Services with Behavior بسازید یا @ngrx/component-store را به عنوان یک جایگزین خوب در نظر بگیرید.

اما، اگر این سناریوی شما نیست و می‌خواهید با NgRx ادامه دهید، سؤالات بعدی را در مورد وضعیت خود بپرسید.

  • آیا توسط بسیاری از مؤلفه ها و خدمات واکشی می شود؟

  • آیا توسط منابع دیگر تداوم یافته و تغییر می کند؟

  • آیا با عمل از منابع دیگر تغییر می کند؟

  • آیا باید برای مسیرها آماده باشد؟

  • آیا این یک عارضه جانبی است؟

اگر بیشتر این سوالات درست باشد، باید از NgRx استفاده کنید. شاید بهترین راه برای فهمیدن اینکه آیا واقعاً نیاز دارد، مثال زیر باشد. Nba.com دارای تعاملات زیادی توسط کاربران است، همچنین نیاز به حفظ وضعیت در روتر، اجزاء، تغییر در فید و موارد دیگر مانند:

  • URL با وضعیت تقویم و فیلترها مرتبط است.

  • تقویم ها داده ها را فیلتر می کنند و کاربر می تواند آن را تغییر دهد، اما URL را نیز به روز کند.

  • فید بازی بازی ها باید به تغییرات در زمان واقعی واکنش نشان دهد.

1

در صورتی که کاربر تعاملات زیادی داشته باشد و اجزاء باید با منابع داده متعدد به آنها واکنش نشان دهند. NgRx مجموعه‌ای از کتابخانه‌ها مانند @ngrx/store، @ngrx/effects، @ngrx/router-store، @ngrx/entity، @ngrx/component-store، @ngrx/signals و @ngrx/operators را برای کمک به ما در ساخت Reactive ارائه می‌کند. و حالت جهانی با جداسازی عوارض جانبی، همچنین مجموعه موجودیت ها را با روتر Angular ادغام می کند و با یک راه آسان برای اشکال زدایی با استفاده از ابزارهای توسعه.

NgRx سازماندهی و مدیریت حالت را آسان می کند زیرا از الگوی REDUX پیروی می کند، بنابراین ما داریم:

  • منبع واحد حقیقت store.

  • ایالت فقط خواندنی است، تنها راه تغییر، ارسال اقدامات است.

  • کاهنده ها عملکردهای خالصی هستند که مسئول تغییر دولت هستند.

  • انتخابگرها را برای دریافت برش خاصی از وضعیت ارائه دهید.

همه این بخش ها دارای یک گردش کاری هستند که باید دنبال شوند و هر یک در طول فرآیند مسئولیت خاص خود را دارند. خب حالا بیایید در مورد گردش کار NgRx بحث کنیم.

گردش کار NgRx

به عنوان مثال، در برنامه Angular من، home.component کاربر را ملزم به پذیرش شرایط و ضوابط می کند. پس از پذیرش، کاربر به صفحه about هدایت می شود. با این حال، هنگامی که آنها به صفحه اصلی باز می گردند، چک باکس شرایط و ضوابط دوباره برداشته می شود 🙃.

چرا برنامه من وضعیت را حفظ نمی کند؟

خوب، home.component از بین رفت و حالت ناپدید شد، وقتی کاربر به about منتقل می‌شود، و home.component وضعیت را در هیچ مکانی ذخیره نمی‌کند، فکر می‌کنم یک مورد کوچک عالی برای حل با NgRx و نشان دادن نحوه عملکرد گردش کار NgRx است.

بله، حل آن با یک موضوع رفتاری آسان است، اما ساده ترین راه برای نشان دادن گردش کار NgRx است.

گردش کار NgRx بر اساس اقدامات، کاهنده، فروشگاه و انتخابگرهااثر در صورت نیاز)، بنابراین گردش کار باید به صورت زیر باشد:

  • مؤلفه یک عمل را تحریک می کند [TermsCondition Page] Accept Terms Conditions

  • این reducer دریافت کنید action ماشه، تابع گرفتن یک کپی از جریان state تغییرات را انجام دهید و وضعیت را به روز کنید.

  • کامپوننت می تواند تغییر حالت را با استفاده از a بخواند selectors یا از جهانی store.

2

پروژه راه اندازی

به جای ساختن یک برنامه از ابتدا، ترجیح می دهم یک مخزن را به عنوان نقطه شروع به شما ارائه دهم. در مورد من، من از Angular با Standalone (بدون ماژول) استفاده می کنم.

ابتدا در ترمینال کد زیر را برای کلون کردن مخزن و نصب وابستگی ها اجرا کنید.

git clone https://github.com/danywalls/start-with-ngrx.git
npm i
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بعد، اجرا کنید ng serve برای شروع برنامه مثال و رفتن به http://localhost:4200. در صفحه اصلی، کادر را علامت بزنید. سپس روی «درباره» کلیک کنید و به «خانه» بازگردید. خواهید دید که چک باکس دیگر علامت نمی خورد.

3

ما سناریو را آماده کرده‌ایم، پس وقت آن است که آن را با استفاده از NgRx برطرف کنیم! ⚒️

NgRx را پیکربندی کنید

سپس ngrx را با اجرای دستور نصب کنید npm i @ngrx/store :

npm i @ngrx/store
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

باز کن app.config.ts فایل. در بخش ارائه دهندگان، از provideStore تابعی برای پیکربندی حالت جهانی. حالت و کاهنده را انتظار دارد، اما چون کاهنده آماده نداریم، فعلاً آن را با یک تابع خالی مقدار دهی اولیه کنید.

import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideStore } from '@ngrx/store';

export const appConfig = {
  providers: [provideRouter(routes), provideStore()],
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در مرحله بعد، باید حالت را برای صفحه اصلی تنظیم کنیم. یک دایرکتوری جدید ایجاد کنید: pages/home/home.state.ts. در داخل، یک رابط ایجاد کنید HomeState و تعریف کنید initialState.

حالت یک شی با ویژگی هایی است که باید توسط حالت نمایش داده شود.

export interface HomeState {
  acceptTerms: boolean
}
const initialState: HomeState = {
  acceptTerms: false,
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ما حالت آماده را داریم، پس بیایید کاهنده را در آن ایجاد کنیم pages/home/state/home.reducer.ts. وارد کنید createReducer عملکرد با initialState و وارد کنید on تابع.

وارد کنید createAction تابع برای تعریف عمل. نام عمل را پاس کنید [Home Page] Accept Terms و به عنوان یک پارامتر، حالت.

از عملگر spread استفاده کنید (...) برای بدست آوردن مقدار فعلی state و به روز رسانی کنید acceptTerms ویژگی.

کد نهایی به نظر می رسد:

import { createAction, createReducer, on } from '@ngrx/store';
import { initialState } from './home.state';

export const homeReducer = createReducer(
  initialState,
  on(createAction('[Home Page] Accept Terms'), (state) => ({
    ...state,
    acceptTerms: !state.acceptTerms,
  })),
);
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

اکنون آماده راه اندازی فروشگاه هستیم. باز کن app.config.ts دوباره فایل کنید و شی slice را با استفاده از به کاهنده اضافه کنید homeReducer.

گزینه دیگر استفاده از provideState است

import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import {provideStore, StoreModule} from "@ngrx/store";
import {homeReducer} from "./pages/home/state/home.reducer";

export const appConfig = {
  providers: [provideRouter(routes),
   provideStore(
     {
       home: homeReducer,
     }
   )
  ]
};
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با استفاده از NgRx

ما در مراحل پایانی هستیم. ابتدا در را باز کنید home.component.ts فایل و تزریق کنید store. بعد، ذخیره کنید $acceptTerms از مغازه. برای این مقاله، می‌خواهم از انتخابگر صرفنظر کنم، بنابراین مستقیماً با استفاده از فروشگاه مشترک می‌شوم select و قابل مشاهده را با استفاده از علامت به سیگنال تبدیل کنید toSignal تابع برای جلوگیری از اشتراک با async لوله

ما یک تغییر کوچک در آن ایجاد می کنیم onChange روش. با استفاده از فروشگاه، اقدامی را برای راه‌اندازی به‌روزرسانی از کاهنده ارسال می‌کنیم.

کد نهایی به شکل زیر است:

export class HomeComponent {
  private _store = inject(Store);
  public $acceptTerms = toSignal(this._store.select((state) => state.home.acceptTerms))

  onChange() {
    this._store.dispatch({
      type: '[Home Page] Accept Terms'
    })
  }
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

در قالب، منطق را برای استفاده از آن به روز کنید $acceptTerms با خواندن مقدار با ().

ذخیره تغییرات و ta-da! 🎉🎉🎉 NgRx اکنون راه اندازی شده است و وضعیت در برنامه ما یکپارچه شده است!

4

نتیجه

ما یاد گرفتیم که چقدر آسان است که یک حالت، اکشن و کاهنده ایجاد کنیم و وضعیت را مستقیماً با استفاده از فروشگاه بخوانیم. با این حال، برای یک کاربرد کوچک، ممکن است مانند صفحه دیگ بخار زیاد به نظر برسد، اما یک نقطه شروع عالی با NgRx است.

ما همچنین نمونه هایی از زمان استفاده از NgRx در سرویس های Angular داریم. می توانید از چک لیست برای تصمیم گیری در مورد اینکه آیا NgRx ضروری است استفاده کنید.

در نهایت، با یک مثال عملی پایه یاد گرفتم که چگونه NgRx را برای مدیریت وضعیت پیکربندی کنم. این شامل راه‌اندازی فروشگاه، ایجاد حالت و کاهش‌دهنده‌ها و ادغام NgRx در یک مؤلفه برای حفظ آسان وضعیت در سراسر ناوبری است.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا