در این مقاله قصد داریم نحوه مدیریت وضعیت ها در انگولار با NGXS را به شما آموزش بدهیم. NGXS یک روش متفاوت برای مدیریت وضعیت در انگولار است. برای مشاهده مستندات این کتابخانه به اینجا مراجعه کنید.
سرفصل های این آموزش
- NGXS چیست؟
- چرخه NGXS
- آموزش NGXS همراه با مثال
- نصب انگولار
- نصب NGXS Store
- ایجاد کامپوننت ها
- تعریف مدل
- تعریف اکشن ها
- تعریف یک وضعیت
- بروزرسانی فایل app.module.ts
- نمایش داده ها
NGXS چیست؟
NGXS یک الگوی مدیریت وضعیت برای فریمورک انگولار است. NGXS به عنوان یک منبع قابل اعتماد برای وضعیت برنامه های شما عمل می کند و قوانین ساده ای را برای تغییرات قابل پیش بینی وضعیت ها ارائه می دهد.
از نظر مفهومی دقیقاً همانند کتابخانه Redux است که بیشتر در برنامه های React مورد استفاده قرار می گیرد. شما نمی توانید بطور مستقیم وضعیت ها را تغییر دهید، بلکه باید یک عمل را انجام دهید و سپس از آن طریق یک وضعیت را بروزرسانی کنید. NGXS پس از الگوی CQRS که در کتابخانه ی محبوب Redux پیاده سازی شده، ساخته شده است، اما با استفاده از ویژگی های مدرن تایپ اسکریپت مانند کلاس و decorator حجم کدهای تکراری برنامه را کاهش می دهد.
چرخه NGXS
چرخه NGXS به شرح زیر است:
- کامپوننت های انگولار عملی (اکشن) را انجام می دهند.
- اگر آن عمل نیاز به تغییر داده های پایگاه داده داشت، یک درخواست به سرور ارسال کرده و عملیات مربوط به پایگاه داده را اجرا می کند.
- سپس بعد از دریافت پاسخ از سرور، وضعیت را تغییر می دهد. اگر back end وجود نداشت، آن عمل (اکشن) بطور مستقیم وضعیت store را تغییر داده و کامپوننت با انتخاب آن وضعیت، رابط کاربری را بروزرسانی می کند.
اگر با Redux آشنایی داشته باشید، می بینید که این چرخه همانند چرخه Redux است. برای کسب اطلاع بیشتر درباره NGXS به مستندات رسمی آن مراجعه کنید.
آموزش Angular NGXS همراه با مثال
این آموزش را با نصب انگولار توسط Angular Cli شروع می کنیم.
1- نصب انگولار
اگر قبلاً Angular Cli را بطور سراسری در سیستم تان نصب نکرده اید، با دستور زیر اینکار را انجام دهید.
|
npm install-g@angular/cli
# or
yarn add global@angular/cli
|
سپس با کد زیر یک پروژه انگولار را ایجاد کنید.
2- نصب NGXS Store
دستور زیر را در Command Line خود وارد کرده تا NGXS نصب شود.
حال logger-plugin و devtools-plugin را به عنوان وابستگی های توسعه، نصب کنید.
|
yarn add@ngxs/logger-plugin@ngxs/devtools-plugin--dev
|
حال این ماژول ها را به داخل فایل app.module.ts، وارد یا import کنید.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
// app.module.ts
import{BrowserModule}from'@angular/platform-browser';
import{NgModule}from'@angular/core';
import{NgxsModule}from'@ngxs/store';
import{NgxsReduxDevtoolsPluginModule}from'@ngxs/devtools-plugin';
import{NgxsLoggerPluginModule}from'@ngxs/logger-plugin';
import{AppComponent}from'./app.component';
@NgModule({
declarations:[
AppComponent
],
imports:[
BrowserModule,
NgxsModule.forRoot(),
NgxsReduxDevtoolsPluginModule.forRoot(),
NgxsLoggerPluginModule.forRoot()
],
providers:[],
bootstrap:[AppComponent]
})
exportclassAppModule{}
|
سپس دستور زیر را برای راه اندازی سرور توسعه انگولار اجرا کنید.
همان طور که در log مرورگر می بینید، هنگامی که یک وضعیت تغییر کند، می توانیم مقادیر قدیم و جدید را مشاهده کنیم.
3– ایجاد کامپوننت ها
یک فولدر به نام components در مسیر src/app ایجاد کنید.
حال اطلاعات کاربر مانند نام و ایمیل را ایجاد و آنها را نمایش می دهیم.
ما در اینجا برای ذخیره اطلاعات کاربران از backend استفاده نمی کنیم.
بلکه باید داده ها را در Store افزوده و آن داده ها را توسط انگولار در frontend برنامه نمایش دهیم.
همچنین با اجرای دستورات زیر در انگولار دو کامپوننت ایجاد می کنیم.
|
nggccomponents/create--spec=false
nggccomponents/index--spec=false
|
سپس با اجرای دستورات زیر در ترمینال، بوت استرپ 4 را نصب می کنیم.
سپس کد زیر را به فایل src/styles.css اضافه کنید.
|
@import"~bootstrap/dist/css/bootstrap.min.css"
|
در مسیر src/app/components/create کدهای زیر را به فایل create.component.html اضافه کنید.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<div class="card">
<div class="card-body">
<form>
<div class="form-group">
<label class="col-md-4">Name</label>
<input type="text"class="form-control"#name/>
</div>
<div class="form-group">
<label class="col-md-4">Email</label>
<input type="email"class="form-control"#email/>
</div>
<div class="form-group">
<button(click)="addUser(name.value, email.value)"class="btn btn-primary">Create User</button>
</div>
</form>
</div>
</div>
|
حال این کامپوننت ها را به داخل فایل app.component.html اضافه کنید.
|
<div class="container">
<div class="row">
<div class="col-md-6">
<app-create></app-create>
</div>
<div class="col-md-6"></div>
</div>
</div>
|
فایل را ذخیره کرده و به آدرس localhost:4200 بروید. نتیجه آن باید مطابق تصویر زیر باشد.
حال نیاز به ReactiveFormsModule داریم. ما در اینجا از روش Reactive به جای روش مبتنی بر قالب، استفاده می کنیم.
برای این منظور داخل فایل app.module.ts، ReactiveFormsModule را از پکیج @angular/forms اضافه می کنیم.
|
// app.module.ts
import{ReactiveFormsModule}from'@angular/forms';
imports:[
BrowserModule,
NgxsModule.forRoot(),
NgxsReduxDevtoolsPluginModule.forRoot(),
NgxsLoggerPluginModule.forRoot(),
ReactiveFormsModule
],
|
حال کدهای زیر را در فایل create.components.ts اضافه کنید.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
// create.component.ts
import{Component,OnInit}from'@angular/core';
import{FormGroup,FormBuilder,Validators}from'@angular/forms';
@Component({
selector:'app-create',
templateUrl:'./create.component.html',
styleUrls:['./create.component.css']
})
exportclassCreateComponentimplementsOnInit{
angForm:FormGroup;
constructor(privatefb:FormBuilder){
this.createForm();
}
createForm(){
this.angForm=this.fb.group({
name:['',Validators.required],
email:['',Validators.required]
});
}
addUser(name,email){
console.log(name,email);
}
ngOnInit(){
}
}
|
و در نهایت کدهای html زیر را به فایل create.component.html اضافه کنید.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<div class="card">
<div class="card-body">
<form[formGroup]="angForm">
<div class="form-group">
<label class="col-md-4">Name</label>
<input type="text"class="form-control"formControlName="name"#name/>
<div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)"class="alert alert-danger">
<div *ngIf="angForm.controls['name'].errors.required">
Name isrequired.
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-4">Email</label>
<input type="email"class="form-control"formControlName="email"#email/>
<div *ngIf="angForm.controls['email'].invalid && (angForm.controls['email'].dirty || angForm.controls['email'].touched)"class="alert alert-danger">
<div *ngIf="angForm.controls['email'].errors.required">
Email isrequired.
</div>
</div>
</div>
<div class="form-group">
<button(click)="addUser(name.value, email.value)"
class="btn btn-primary"
[disabled]="angForm.pristine || angForm.invalid">Create User</button>
</div>
</form>
</div>
</div>
|
4- تعریف مدل
یک فولدر به نام models در مسیر src/app ایجاد کنید و داخل آن یک فایل با نام User.ts ایجاد کنید.
|
// User.ts
exportinterfaceUser{
name:string;
email:string;
}
|
5– تعریف اکشن ها
حال یک اکشن به نام addUser ایجاد می کنیم. یک فولدر به نام actions در مسیر src/app ایجاد کرده و یک فایل با نام user.action.ts در فولدر actions ایجاد کنید.
|
// user.action.ts
import{User}from'../models/User';
exportclassAddUser{
staticreadonly type='[User] Add';
constructor(publicpayload:User){}
}
|
6– تعریف یک وضعیت
تفاوت کلیدی بین NGRX و NGXS در چگونگی مدیریت وضعیت هاست.
یک فولدر به نام state در مسیر src/app ایجاد کرده و سپس یک فایل به نام user.state.ts در آن فولدر ایجاد کنید.
کدهای زیر را در فایل user.state.ts اضافه کنید.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
// user.action.ts
import{State,Action,StateContext,Selector}from'@ngxs/store';
import{User}from'../models/User';
import{AddUser}from'../actions/user.action';
exportclassUserStateModel{
users:User[];
}
@State<UserStateModel>({
name:'users',
defaults:{
users:[]
}
})
exportclassUserState{
@Selector()
staticgetUsers(state:UserStateModel){
returnstate.users;
}
@Action(AddUser)
add({getState,patchState}:StateContext<UserStateModel>,{payload}:AddUser){
conststate=getState();
patchState({
users:[...state.users,payload]
});
}
}
|
در بالا یک اکشن برای ذخیره داده های کاربر در store تعریف کردیم. هنگامی که کاربر بخواهد کاربر جدیدی را ایجاد کند، ما آن مقدار را گرفته و به آرایه وضعیت کاربرها اضافه میکنیم.
بنابراین هنگامی که کاربر ساخته شد، Store وضعیت کاربرها را بروزرسانی کرده و سپس آن وضعیت توسط کامپوننت دیگری مورد استفاده قرار میگیرد.
در این مثال آن کامپوننت index.component.ts است. بنابراین آن کامپوننت رابط کاربری را تغییر داده و کاربری که جدیداً ساخته شده را نمایش می دهد.
در نهایت، store را به داخل فایل create.component.ts، وارد یا import می کنیم.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
// create.component.ts
import{Component,OnInit}from'@angular/core';
import{Store}from'@ngxs/store';
import{FormGroup,FormBuilder,Validators}from'@angular/forms';
import{AddUser}from'../../actions/user.action';
@Component({
selector:'app-create',
templateUrl:'./create.component.html',
styleUrls:['./create.component.css']
})
exportclassCreateComponentimplementsOnInit{
angForm:FormGroup;
constructor(privatefb:FormBuilder,privatestore:Store){
this.createForm();
}
createForm(){
this.angForm=this.fb.group({
name:['',Validators.required],
email:['',Validators.required]
});
}
addUser(name,email){
this.store.dispatch(newAddUser({name,email}));
}
ngOnInit(){
}
}
|
7- بروزرسانی فایل app.module.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// user.state.ts
import{UserState}from'./state/user.state';
imports:[
BrowserModule,
NgxsModule.forRoot([
UserState
]),
NgxsReduxDevtoolsPluginModule.forRoot(),
NgxsLoggerPluginModule.forRoot(),
ReactiveFormsModule
],
|
8– نمایش داده ها
کدهای زیر را داخل فایل index.component.ts اضافه کنید.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
// index.component.ts
import{Component,OnInit}from'@angular/core';
import{Store,Select}from'@ngxs/store';
import{User}from'../../models/User';
import{Observable}from'rxjs';
@Component({
selector:'app-index',
templateUrl:'./index.component.html',
styleUrls:['./index.component.css']
})
exportclassIndexComponentimplementsOnInit{
users:Observable<User>;
constructor(privatestore:Store){
this.users=this.store.select(state=>state.users.users);
}
ngOnInit(){
}
}
|
در بالا اگر آرایه وضعیت کاربرها تغییر کند، این کامپوننت رندر می شود و تغییرات اتفاق افتاده را نمایش می دهد.
برای مثال اگر کاربر جدیدی اضافه شود، این کامپوننت رندر شده و کاربر جدید را نمایش می دهد.
همچنین کدهای زیر را در فایل index.component.html اضافه کنید.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<div *ngIf="users">
<table class="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let user of users | async">
<td>{{user.name}}</td>
<td>{{user.email}}</td>
</tr>
</tbody>
</table>
</div>
|
حال باید این کامپوننت را به فایل app.component.html، وارد import کنیم.
|
<div class="container">
<div class="row">
<div class="col-md-6">
<app-create></app-create>
</div>
<div class="col-md-6">
<app-index></app-index>
</div>
</div>
</div>
|
فایل را ذخیره کنید. نتیجه را در تصویر زیر می بینید.
به این ترتیب آموزش مدیریت وضعیت در انگولار با NGXS مان به پایان رسید.
کدهای این برنامه را می توانید از این آدرس گیت هاب دریافت کنید.
منبع: روکسو