ホームページ > ウェブフロントエンド > jsチュートリアル > Angular での状態管理に ngrx/store を使用する

Angular での状態管理に ngrx/store を使用する

青灯夜游
リリース: 2020-09-15 10:28:52
転載
4372 人が閲覧しました

Angular での状態管理に ngrx/store を使用する

はじめに

ngrx/store は Redux からインスピレーションを受けており、RxJS と統合された Angular 状態管理ライブラリであり、Angular エバンジェリストの Rob Wormald によって開発されました。 Redux と同じ基本的な考え方を持っていますが、RxJS を使用してオブザーバー パターンを実装します。 Redux の核となる原則に従いますが、Angular 専用に設計されています。

Angular の状態管理のほとんどはサービスによって引き継がれます。一部の中規模および大規模プロジェクトでは、これによる欠点が明らかになります。その 1 つは、状態の流れが混沌としており、役に立たないことです。その後、redux の状態管理モデルを利用し、rxjs フロー プログラミングの特性と組み合わせて、Angular の状態管理ツールである @ngrx/store を形成します。チュートリアル: "

Angular チュートリアル
>>

StoreModule:
    StoreModule は @ngrx/store API のモジュールであり、リデューサーを構成するために使用されます。アプリケーションモジュール。

  • アクション:
  • アクションは状態の変化です。イベントの発生について説明しますが、アプリケーションの状態がどのように変化するかについては指定しません。

  • Store:
  • これは、リデューサーと連携する Store.select() と Store.dispatch() を提供します。 Store.select() はセレクターを選択するために使用されます。
  • Store.dispatch(

    {

    type:'add',
    payload:{name:'111'} }
    )
    アクションをリデューサーに分散するために使用されるタイプ。


    #@NgRx/Store 状態管理の 3 原則

  • まず、@NgRx/Store は Redux の 3 つの基本原則にも準拠しています:

単一データ ソース

    この原則は、単一ページ アプリケーション全体の状態がオブジェクト ツリーの形式でストアに保存されるというものです。
  • この定義は非常に抽象的です。実際には、共有する必要があるすべてのデータを JavaScript オブジェクトの形式で保存することです。
  • state ={
        application:'angular app',
        shoppingList:['apple', 'pear']
    }
    ログイン後にコピー

state は読み取り専用です (状態は読み取り専用です)。読み取り専用形式のみ)

    ngrx/store の中核的な機能の 1 つは、ユーザーがステータスの内容を直接変更できないことです。たとえば、ログイン ページのステータスを保存する必要がある場合、ステータス情報にはログインしているユーザーの名前が記録される必要があります。ログイン名が変更された場合、状態に保存されているユーザー名を直接変更することはできません
  • state={'username':'kat'},
    //用户重新登录别的账户为tom
    state.username = 'tom'  //在ngrx store 这个行为是绝对不允许的
    ログイン後にコピー
変更は純粋な関数で行われます (状態は関数を呼び出すことによってのみ変更できます)

    状態を直接変更できないため、ngrx/store にはレデューサー (アグリゲーター) と呼ばれる概念も導入されています。レデューサーを通じて状態を変更します。
  • function reducer(state = 'SHOW_ALL', action) {
        switch (action.type) {
          	case 'SET_VISIBILITY_FILTER':
            	return Object.assign({}, state  ,newObj);  
            default:
            	return state  
            }
    	}
    ログイン後にコピー
  • ngrx/store 使用例

1. @ngrx/store をインストール

yarn add @ngrx/store

2. ステート、アクション、 raiser

state 状態:

app\store\state.ts

//下面是使用接口的情况, 更规范
export interface TaskList {
  id: number;
  text: string;
  complete: boolean;
}

export const TASKSAll: TaskList[] = [
  {id: 1, text: 'Java Article 1', complete: false},
  {id: 2, text: 'Java Article 2', complete: false}
]

export interface AppState {
  count: number;
  todos: TaskList;
  // 如果要管理多个状态,在这个接口中添加即可
}

//这个是不用接口的情况
// export interface AppState {
//     count: number;
//     todos: any;
//     // 如果要管理多个状态,在这个接口中添加即可
//   }
ログイン後にコピー
reducer

app\store\reducer.ts

// reducer.ts,一般需要将state,action,reducer进行文件拆分
import { Action } from '@ngrx/store';

export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
export const RESET = 'RESET';

const initialState = 0;
// reducer定义了action被派发时state的具体改变方式
export function counterReducer(state: number = initialState, action: Action) {
  switch (action.type) {
    case INCREMENT:
      return state + 1;

    case DECREMENT:
      return state - 1;

    case RESET:
      return 0;

    default:
      return state;
  }
}
ログイン後にコピー
actions

アクションを個別に抽出する必要がある場合は、次を参照してください。 5 アクションを分離したい場合はどうすればよいですか?

3.store


ルート モジュールを登録します:

app/app.module.ts

import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
// StoreModule: StoreModule是@ngrx/storeAPI中的一个模块,
// 它被用来在应用模块中配置reducer。

import {counterReducer} from './store/reducer';

@NgModule({
  imports: [
  	StoreModule.forRoot({ count: counterReducer }), // 注册store
  ],
})
export class AppModule {}
ログイン後にコピー

4. コンポーネントで store


を使用するか、使用するためにストアにサービスを挿入します。

app\module\article\article.component.ts コンポーネントを例として取り上げます:

// 组件级别
import { Component } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs';
import { INCREMENT, DECREMENT, RESET} from '../../store/reducer';

interface AppState {
  count: number;
}

@Component({
  selector: 'app-article',
  templateUrl: './article.component.html',
  styleUrls: ['./article.component.css']
})
export class ArticleComponent  {
  count: Observable<number>;

  constructor(private store: Store<AppState>) { // 注入store
    this.count = store.pipe(select(&#39;count&#39;)); 
    // 从app.module.ts中获取count状态流
  }

  increment() {
    this.store.dispatch({ type: INCREMENT });
  }

  decrement() {
    this.store.dispatch({ type: DECREMENT });
  }

  reset() {
    this.store.dispatch({ type: RESET });
  }
}
ログイン後にコピー

テンプレート ページ:

app\module\article\ Article.component.html

<div class="state-count">

    <button (click)="increment()">增加Increment</button>
    <div>Current Count: {{ count | async }}</div>
    <button (click)="decrement()">减少Decrement</button>

    <button (click)="reset()">Reset Counter</button>
</div>
ログイン後にコピー

ここではパイプ シンボル async が使用されています。これをサブモジュールで直接使用すると、エラーが報告されます。サブモジュールの場合、エラーも報告されます。具体的な理由については、コースウェアで説明されている問題を参照してください: パイプ ' async' が見つかりませんか?


テンプレート ページでパイプを使用せずにページをレンダリングするにはどうすればよいですか?

次のように変更します:

count: Observable<number>;

constructor(private store: Store<AppState>) { // 注入store
    var stream = store.pipe(select(&#39;count&#39;)); 
    // 从app.module.ts中获取count状态流
    stream.subscribe((res)=>{
          this.count = res;
      })
  }
ログイン後にコピー

管理の便宜のため、タイプ、状態、アクション、リデューサーは通常個別に管理されます

5アクションを分割するにはどうすればよいですか?

新しい \app\store\actions.ts ファイルを作成します

import { Injectable } from &#39;@angular/core&#39;;
import { INCREMENT, DECREMENT, RESET } from &#39;./types&#39;;

@Injectable()
export class CounterAction{
    // Add=function(){}
    Add(){
        return { type: INCREMENT }
    }
}

// 就只这样导出是不行的
// export function Add1(){
//     return { type: INCREMENT }
// }
ログイン後にコピー
  1. ルート モジュール app.module.ts
に登録します
import {CounterAction} from &#39;./store/actions&#39;;

... 

providers: [CounterAction],
ログイン後にコピー
  1. コンポーネントで使用 –article.component.ts
import {CounterAction} from &#39;../../store/actions&#39;;

export class ArticleComponent implements OnInit {

  constructor(
    private action: CounterAction  //注入CounterAction
    ) { }

    increment() {
    // this.store.dispatch({ type: INCREMENT }); 
    //把 actions分离出去
    this.store.dispatch(this.action.Add()); 
    
  }
}
ログイン後にコピー
    プログラミング関連の知識の詳細については、
  1. プログラミング入門
  2. を参照してください。 !

以上がAngular での状態管理に ngrx/store を使用するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:csdn.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート