مدیریت وضعیت (State Management)
«مدیریت وضعیت» یعنی نظم دادن به تغییرات داده در زمان. اول محلی نگه دار. سپس در صورت نیاز، وضعیت را به «سرویس» ارتقا بده. با «سیگنال (signal)» مقدار زنده می گیری و با «محاسبه ای (computed)» مقدار مشتق می سازی.
مبانی مدیریت وضعیت
ابتدا از سیگنال در کامپوننت استفاده کن. وقتی اشتراک لازم شد، وضعیت را به سرویس ببر. تنها وقتی به رفتار جریانی نیاز داری، سراغ RxJS برو.
import { Injectable } from '@angular/core';
import { signal } from '@angular/core';
import { computed } from '@angular/core';
import { inject } from '@angular/core';
@Injectable({ providedIn: 'root' })
class CounterStore {
count = signal(0);
double = computed(() => this.count() * 2);
inc() {
this.count.update((n) => n + 1);
}
}
// Component usage
// const store = inject(CounterStore);
سیگنال های پشتیبانی شده با سرویس
«سرویس (Service)» محل مشترک وضعیت است. بنابراین چند کامپوننت به همان منبع وصل می شوند. در نتیجه هم زمان می مانند.
import { Injectable } from '@angular/core';
import { signal } from '@angular/core';
import { inject } from '@angular/core';
@Injectable({ providedIn: 'root' })
class CounterStore {
count = signal(0);
inc() {
this.count.update((n) => n + 1);
}
}
class App {
store = inject(CounterStore);
}
نمونه کامل: سرویس + سیگنال
در این نمونه سرویس شمارنده می سازیم. سپس در کامپوننت تزریق می کنیم. با کلیک، مقدار افزایش می یابد.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component } from '@angular/core';
import { Injectable } from '@angular/core';
import { signal } from '@angular/core';
import { inject } from '@angular/core';
@Injectable({ providedIn: 'root' })
class CounterStore {
count = signal(0);
inc() {
this.count.update((n) => n + 1);
}
}
@Component({
selector: 'app-root',
standalone: true,
template: `
<h3>Service with Signals</h3>
<p>Count: {{ store.count() }}</p>
<button (click)=\"store.inc()\">Increment</button>
`,
})
class App {
store = inject(CounterStore);
}
bootstrapApplication(App);
وضعیت محلی یا سراسری؟
اکثر وضعیت ها محلی بمانند. وقتی چند مسیر نیاز دارند، آن را به سرویس ارتقا بده. همچنین می توانی دامنه سرویس را در سطح مسیر محدود کنی.
import { provideRouter } from '@angular/router';
import { Routes } from '@angular/router';
const routes: Routes = [
{ path: '', component: Home, providers: [CounterStore] },
];
bootstrapApplication(App, {
providers: [provideRouter(routes)],
});
گام های عملی
- اول وضعیت را در کامپوننت با signal بساز.
- نیاز به اشتراک داشتی، یک سرویس بساز.
- متدهای تغییر را فقط در سرویس نگه دار.
- برای مقادیر مشتق، computed تعریف کن.
- دامنه سرویس را در سطح ویژگی محدود کن.
نکته: وضعیت رابط کاربری را از وضعیت سرور جدا نگه دار. بنابراین ساده تر تست می شود.
جمع بندی سریع
- اول محلی، بعد سرویسی.
- متدها در سرویس بمانند.
- computed برای مقادیر مشتق است.
- دامنه سرویس را محدود کن.
- فقط گاهی سراغ RxJS برو.
مطالب مرتبط: فرم های پیشرفته، روتر پیشرفته، اینترسپتورهای HTTP.