>  기사  >  웹 프론트엔드  >  Angular에서 상태 관리를 위해 ngrx/store 사용

Angular에서 상태 관리를 위해 ngrx/store 사용

青灯夜游
青灯夜游앞으로
2020-09-15 10:28:524340검색

Angular에서 상태 관리를 위해 ngrx/store 사용

Introduction

ngrx/store은 Redux에서 영감을 받았으며 Angular 전도사 Rob Wormald가 개발한 RxJS를 통합한 Angular 상태 관리 라이브러리입니다. Redux와 핵심 아이디어는 동일하지만 RxJS를 사용하여 관찰자 패턴을 구현합니다. 핵심 Redux 원칙을 따르지만 Angular를 위해 특별히 설계되었습니다.

Angular의 대부분의 상태 관리는 서비스로 인계될 수 있습니다. 일부 중대형 프로젝트에서는 이에 대한 단점이 드러납니다. 그 중 하나는 상태 흐름이 혼란스러워 향후 유지 관리에 도움이 되지 않는다는 것입니다. 나중에 redux가 rxjs 흐름 프로그래밍의 특성과 결합되어 Angular의 상태 관리 도구인 @ngrx/store를 참조했습니다.

추천 관련 튜토리얼: "angular Tutorial"

  • StoreModule:
    StoreModule은 @ngrx/store API에 있는 모듈로, 애플리케이션 모듈에서 리듀서를 구성하는 데 사용됩니다.

  • 액션:
    액션은 상태의 변화입니다. 이벤트 발생을 설명하지만 애플리케이션의 상태가 어떻게 변경되는지는 지정하지 않습니다.

  • Store:
    리듀서 작업을 위해 Store.select() 및 Store.dispatch()를 제공합니다. Store.select()는 선택기를 선택하는 데 사용되며,
    Store.dispatch(
    {
    type: 'add',
    payload: {name: '111'}
    }
    )
    은 작업 유형을 배포하는 데 사용됩니다. 감속기에.

@NgRx/Store 상태 관리의 세 가지 원칙

우선, @NgRx/Store도 Redux의 세 가지 기본 원칙을 준수합니다.

  • 단일 데이터 소스

이 원칙은 전체 단일 페이지 애플리케이션이 전달됩니다. 개체 트리가 저장소에 저장됩니다.
이 정의는 사실 공유해야 하는 모든 데이터를 자바스크립트 객체 형태로 저장하는 것입니다. 상태 내용은 직접 수정할 수 없습니다. 예를 들어 로그인 페이지의 상태를 저장해야 하는 경우 상태 정보에는 로그인한 사용자의 이름이 기록되어야 합니다. 로그인 이름이 변경되면 상태에 저장된 사용자 이름을 직접 수정할 수 없습니다

state ={
    application:'angular app',
    shoppingList:['apple', 'pear']
}
  • 변경은 순수 함수로 이루어집니다(상태는 함수를 호출해야만 변경할 수 있습니다)

상태를 직접 변경할 수 없으므로 ngrx /store는 또한 Reducer(Aggregator)라는 개념을 도입했습니다. 리듀서를 통해 상태를 수정합니다.

state={'username':'kat'},
//用户重新登录别的账户为tom
state.username = 'tom'  //在ngrx store 这个行为是绝对不允许的
    ngrx/store 사용 예
  • 1. @ngrx/store 설치

yarn 추가 @ngrx/store

2. 상태, 작업, Reducer

상태 상태:

appstorestate.ts

function reducer(state = 'SHOW_ALL', action) {
    switch (action.type) {
      	case 'SET_VISIBILITY_FILTER':
        	return Object.assign({}, state  ,newObj);  
        default:
        	return state  
        }
	}

Reducer appstorereducer.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;
//     // 如果要管理多个状态,在这个接口中添加即可
//   }

actions
액션을 별도로 추출해야 하는 경우에는 다음을 참고하세요

5. 액션을 분리하고 싶다면 어떻게 해야 하나요?

3. 스토어 등록

루트 모듈:

app/app.module.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;
  }
}

4. 스토어 사용

스토어를 컴포넌트 또는 서비스에 삽입하여 사용하세요


appmodulearticlearticle.comComponent.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 {}

템플릿 페이지:

appmodulearticlearticle.comComponent.html

// 组件级别
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 });
  }
}

여기서는 파이프 기호 비동기가 사용되며, 데이터의 양방향 바인딩이 구현되는 경우 빠른 오류 보고가 하위 모듈에서 직접 사용됩니다. 하위 모듈에서도 오류가 보고됩니다. 구체적인 이유로 코스웨어 설명을 참조하세요. 질문: 'async' 파이프를 찾을 수 없습니다.

템플릿 페이지에서 파이프를 사용하지 않고 페이지를 렌더링하는 방법은 무엇입니까?

다음과 같이 수정합니다.

<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>

관리의 편의를 위해 타입, 상태, 액션, 리듀서는 일반적으로 별도로 관리합니다.

5 액션을 분리하고 싶다면 어떻게 해야 할까요?

새 appstoreactions.ts 파일 만들기

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;
      })
  }

루트 모듈 app.module.ts에 등록
  1. 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 }
    // }
컴포넌트에서 사용 – ​article.comComponent.ts
  1. import {CounterAction} from &#39;./store/actions&#39;;
    
    ... 
    
    providers: [CounterAction],
  2. 더 많은 프로그래밍을 위해- 관련 지식이 있는 경우
프로그래밍 입문
    을 방문하세요! !

위 내용은 Angular에서 상태 관리를 위해 ngrx/store 사용의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제