Artikel ini akan memberi Anda pemahaman mendalam tentang state manager Angular NgRx dan memperkenalkan cara menggunakan NgRx. Saya harap ini dapat membantu Anda!
NgRx adalah solusi arsitektur Redux untuk manajemen status global dalam aplikasi Angular. [Tutorial terkait yang direkomendasikan: "tutorial sudut"]
@ngrx/store: modul manajemen keadaan global
@ngrx/effects: Menangani efek samping
@ngrx/store-devtools: Alat debugging browser, harus mengandalkan Ekstensi Redux Devtools
@ngrx/schematics: alat baris perintah untuk menghasilkan file NgRx dengan cepat
@ngrx/entity: Meningkatkan efisiensi pengembang dalam mengoperasikan data di Reducer
@ngrx/router-store: Menyinkronkan status perutean ke Penyimpanan global
1. Unduh NgRx
npm install @ngrx/store @ngrx/effects @ngrx/entity @ngrx/router-store @ngrx/store-devtools @ngrx/schematics
2. Konfigurasikan NgRx CLI
ng config cli.defaultCollection @ngrx/schematics
// sudut.json "kli": { "koleksi default": "@ngrx/schematics" }
3. Buat Toko
ng g store State --root --module app.module.ts --statePath store --stateInterface AppState
4. Buat Aksi
ng g action store/actions/counter --skipTests
impor { createAction } dari "@ngrx/store" ekspor kenaikan const = createAction("kenaikan") ekspor pengurangan const = createAction("pengurangan")
5. Buat Peredam
ng g reducer store/reducers/counter --skipTests --reducers=../index.ts
impor { createReducer, aktif } dari "@ngrx/store" impor { pengurangan, kenaikan } dari "../actions/counter.actions" ekspor const counterFeatureKey = "penghitung" ekspor antarmuka Negara { hitungan: angka } ekspor const keadaan awal: Negara = { hitungan: 0 } ekspor const peredam = createReducer( keadaan awal, on(kenaikan, status => ({ hitungan: status.hitungan + 1 })), aktif(pengurangan, status => ({ hitungan: status.hitungan - 1 })) )
6. Buat Pemilih
ng g selector store/selectors/counter --skipTests
impor { createFeatureSelector, createSelector } dari "@ngrx/store" impor { counterFeatureKey, State } dari "../reducers/counter.reducer" impor { AppState } dari ".." ekspor const selectCounter = createFeatureSelector<AppState, State>(counterFeatureKey) ekspor const selectCount = createSelector(selectCounter, negara bagian => negara bagian.hitungan)
7. Kelas komponen memicu Aksi dan memperoleh status
impor { pilih, Simpan } dari "@ngrx/store" impor {Dapat Diamati } dari "rxjs" impor { AppState } dari "./store" impor { pengurangan, kenaikan } dari "./store/actions/counter.actions" impor { selectCount } dari "./store/selectors/counter.selectors" kelas ekspor Komponen Aplikasi { count: Dapat diamati<angka> konstruktor(toko pribadi: Store<AppState>) { this.count = this.store.pipe(pilih(selectCount)) } kenaikan() { this.store.dispatch(peningkatan()) } pengurangan() { this.store.dispatch(pengurangan()) } }
8. Status tampilan template komponen
<tombol (klik)="peningkatan()">+</button> <span>{{ hitungan |.asinkron }}</span> <tombol (klik)="penurunan()">-</button>
1. Gunakan pengiriman di komponen untuk meneruskan parameter saat memicu Aksi, dan parameter tersebut pada akhirnya akan ditempatkan di objek Aksi.
this.store.dispatch(kenaikan({ hitungan: 5 }))
2. Saat membuat fungsi Action Creator, dapatkan parameternya dan tentukan jenis parameternya.
impor { createAction, props } dari "@ngrx/store" ekspor kenaikan const = createAction("kenaikan", alat peraga<{ hitungan: angka }>())
ekspor mendeklarasikan fungsi props<P extends object>(): Props<P>;
3. Dapatkan parameter melalui objek Action di Reducer.
ekspor const peredam = createReducer( keadaan awal, on(kenaikan, (status, tindakan) => ({ hitungan: status.hitungan + tindakan.hitungan })) )
metaReducer adalah penghubung antara Action -> Reducer, yang memungkinkan pengembang untuk melakukan praproses Action (dipanggil sebelum pemanggilan fungsi Reducer biasa).
debug fungsi(peredam: ActionReducer<any>): ActionReducer<any> { fungsi pengembalian (keadaan, tindakan) { peredam pengembalian (status, tindakan) } } ekspor const metaReducers: MetaReducer<AppState>[] = !environment.production ?[debug] : []
Persyaratan: Tambahkan tombol ke halaman. Setelah mengklik tombol, tunda satu detik agar nilainya meningkat.
1. Tambahkan tombol untuk kenaikan nilai asinkron di templat komponen. Setelah tombol diklik, metode increment_async
dijalankan.
<button (klik)="inclinement_async()">asinkron</button>
2. Tambahkan metode increment_async
ke kelas komponen dan picu Tindakan untuk melakukan operasi asinkron dalam metode tersebut.
kenaikan_async() { ini.toko.pengiriman(peningkatan_async()) }
3. Tambahkan Tindakan untuk melakukan operasi asinkron di file Tindakan.
ekspor const incredit_async = createAction("inkrement_async")
4. Buat Efek, terima Aksi dan lakukan efek samping, lalu lanjutkan memicu Aksi
ng g effect store/effects/counter --root --module app.module.ts --skipTests
Fungsi Efek disediakan oleh modul @ngrx/effects, sehingga dependensi modul yang relevan perlu diimpor ke modul root.
impor { Suntikan } dari "@angular/core" impor { Tindakan, createEffect, ofType } dari "@ngrx/effects" impor { kenaikan, kenaikan_async } dari "../actions/counter.actions" impor { mergeMap, map } dari "rxjs/operator" impor { timer } dari "rxjs" // buatEfek // Digunakan untuk membuat Efek, Efek digunakan untuk melakukan efek samping. // Teruskan fungsi callback saat memanggil metode, dan kembalikan objek Observable di fungsi callback. Objek Action yang akan dipicu setelah efek samping dieksekusi // Nilai kembalian dari fungsi callback terus dikembalikan di dalam createEffect metode, dan nilai akhir yang dikembalikan disimpan dalam properti kelas Efek // Setelah membuat instance kelas Efek, NgRx akan berlangganan properti kelas Efek. Ketika efek samping selesai, ia akan memperoleh objek Aksi yang akan dipicu dan memicu Aksi. //Tindakan // Ketika sebuah komponen memicu suatu Action, Effect perlu menerima Action melalui layanan Actions, jadi di kelas Effect, objek instance dari kelas layanan Actions dimasukkan ke dalam kelas Effect melalui parameter konstruktor objek kelas layanan Tindakan adalah Objek yang Dapat Diamati, ketika suatu Tindakan dipicu, objek Tindakan itu sendiri akan dipancarkan sebagai aliran data // ofType // Filter objek Aksi target. // Parameternya adalah fungsi Action Creator dari Action target // Jika objek Action target tidak difilter, aliran data tidak akan terus dikirim saat ini // Jika objek Action target difilter, objek Action akan terus dikirim sebagai aliran data @Injectable() ekspor kelas CounterEffects { konstruktor(tindakan pribadi: Tindakan) { // this.loadCount.subscribe(konsol.log) } loadCount = buatEffect(() => { kembalikan ini.tindakan.pipa( ofType(peningkatan_async), mergeMap(() => timer(1000).pipe(map(() => kenaikan({ hitungan: 10 })))) ) }) }
1. Ikhtisar
Entitas diterjemahkan sebagai entitas, dan entitas adalah bagian data dalam kumpulan.
NgRx menyediakan objek adaptor entitas. Di bawah objek adaptor entitas, berbagai metode untuk entitas operasi dalam koleksi disediakan.
2. Inti
1. EntityState: Antarmuka tipe entitas
/* { ID: [1, 2], entitas: { 1: { id: 1, judul: "Halo Angular" }, 2: { id: 2, judul: "Halo NgRx" } } } */ ekspor antarmuka Negara memperluas EntityState<Todo> {}
2. createEntityAdapter: Membuat objek adaptor entitas
3. EntityAdapter: Antarmuka tipe objek adaptor entitas
ekspor adaptor const: EntityAdapter<Todo> = createEntityAdapter<Todo>() // Dapatkan status awal. Anda bisa meneruskan parameter objek atau tidak. // {id: [], entitas: {}} ekspor const keadaan awal: Status = adaptor.getInitialState()
3. Metode contoh
https://ngrx.io/guide/entity/adapter#adapter-collection-methods
4. Pemilih
// selectTotal mendapatkan jumlah item data // selectAll mendapatkan semua data dan menyajikannya dalam bentuk array // selectEntities mendapatkan kumpulan entitas dan menyajikannya dalam bentuk kamus // selectIds mendapatkan kumpulan id dan menyajikannya berbentuk array const { selectIds, selectEntities, selectAll, selectTotal } = adapter .getSelectors();
ekspor const selectTodo = createFeatureSelector<AppState, State>(todoFeatureKey) ekspor const selectTodos = createSelector(selectTodo, selectAll)
1. Sinkronisasi status perutean
1) Perkenalkan modul
impor { StoreRouterConnectingModule } dari "@ngrx/router-store" @NgModule({ impor: [ StoreRouterConnectingModule.forRoot() ] }) ekspor kelas AppModule {}
2) Integrasikan status perutean ke Store
impor * sebagai fromRouter dari "@ngrx/router-store" ekspor antarmuka AppState { router: dariRouter.RouterReducerState } ekspor pengurang const: ActionReducerMap<AppState> = { router: dariRouter.routerReducer }
2. Buat Selector untuk mendapatkan status routing
// router.selectors.ts impor { createFeatureSelector } dari "@ngrx/store" impor { AppState } dari ".." impor { RouterReducerState, getSelectors } dari "@ngrx/router-store" const selectRouter = createFeatureSelector<AppState, RouterReducerState>( "perute" ) ekspor konstan { // Mendapatkan informasi terkait rute saat ini (parameter perutean, konfigurasi perutean, dll.) pilihRute Saat Ini, // Dapatkan konten setelah nomor # di bilah alamat selectFragment, // Dapatkan parameter kueri perutean selectQueryParams, // Dapatkan parameter kueri spesifik selectQueryParam('name') pilihQueryParam, // Dapatkan parameter perutean dinamis selectRouteParams, // Dapatkan parameter perutean dinamis tertentu selectRouteParam('name') pilihRouteParam, // Dapatkan data khusus rute selectRouteData, // Dapatkan alamat akses sebenarnya dari rute selectUrl } = getSelectors(pilihRouter)
// rumah.komponen.ts impor { pilih, Simpan } dari "@ngrx/store" impor {AppState} dari "src/app/store" impor { selectQueryParams } dari "src/app/store/selectors/router.selectors" kelas ekspor Tentang Komponen { konstruktor(toko pribadi: Store<AppState>) { this.store.pipe(pilih(selectQueryParams)).berlangganan(konsol.log) } }