Star wars API를 사용한 Angular NGRX

18430 단어 angularswapingrx
이 기사에서는 ngrxStar Wars API을 사용하여 각도 응용 프로그램을 만들 것입니다. ngrx가 무엇인지 이해하고 각도를 사용하여 어떻게 할 수 있는지 이해하려면 ngrxdocumentation로 이동합니다.

NgRx란?

NgRx는 Angular에서 반응형 애플리케이션을 구축하기 위한 프레임워크입니다. NgRx는 다음에 대한 라이브러리를 제공합니다.
  • 글로벌 및 로컬 상태를 관리합니다.
  • 보다 깨끗한 구성 요소 아키텍처를 촉진하기 위해 부작용을 격리합니다.
  • 엔티티 수집 관리.
  • Angular 라우터와 통합.
  • 다양한 유형의 응용 프로그램을 구축할 때 개발자 경험을 향상시키는 개발자 도구입니다.



  • 가게

    NgRx Store는 상태 변경을 표현하기 위해 단일 상태 및 작업을 사용하여 유지 관리 가능하고 명시적인 응용 프로그램을 만들기 위한 상태 관리를 제공합니다. 상태를 관리하기 위해 애플리케이션 전반에 걸친 글로벌 솔루션이 필요하지 않은 경우 로컬 상태 관리를 위한 솔루션을 제공하는 NgRx ComponentStore를 사용하는 것이 좋습니다.

    효과

    서비스 기반 Angular 애플리케이션에서 구성 요소는 서비스를 통해 직접 외부 리소스와 상호 작용합니다. 대신 효과는 해당 서비스와 상호 작용하고 구성 요소에서 격리하는 방법을 제공합니다. 효과는 데이터 가져오기, 여러 이벤트를 생성하는 장기 실행 작업, 구성 요소가 이러한 상호 작용에 대한 명시적인 지식이 필요하지 않은 기타 외부 상호 작용과 같은 작업을 처리하는 곳입니다.

    감속기

    상태 인터페이스, 감속기의 초기 상태 개체 및 감속기 함수를 포함하는 감속기 파일을 생성합니다.

    행위

    액션은 NgRx의 주요 빌딩 블록 중 하나입니다. 작업은 애플리케이션 전체에서 발생하는 고유한 이벤트를 나타냅니다. 페이지와의 사용자 상호 작용, 네트워크 요청을 통한 외부 상호 작용 및 장치 API와의 직접적인 상호 작용에서 이러한 이벤트 및 더 많은 이벤트가 작업으로 설명됩니다.

    앱을 만들겠습니다. 먼저 "시작하기"링크here를 찾을 수 있는 각도 앱을 만들어야 합니다. 백엔드의 경우SWAPI를 사용합니다.

    애플리케이션용 감속기를 생성하겠습니다. 먼저 "reducers"폴더를 생성하고 내부에 index.ts 파일을 생성해야 합니다.

    import {
      ActionReducerMap,
      createFeatureSelector,
      createSelector,
      MetaReducer
    } from '@ngrx/store';
    import { environment } from '../../environments/environment';
    import * as fromMovies from '../movies/movies.reducer';
    
    export interface State {
      movies: fromMovies.State;
    }
    
    export const reducers: ActionReducerMap<State> = {
      movies: fromMovies.reducer,
    };
    
    
    export const metaReducers: MetaReducer<State>[] = !environment.production ? [] : [];
    
    export const getMoviesState = createFeatureSelector<fromMovies.State>('movies');
    export const getMovies = createSelector(getMoviesState, state => state.data);
    export const getIsLoading = createSelector(getMoviesState, state => state.isLoading);
    export const getMovieCharacters = createSelector(getMoviesState, state => state.selectedMovieCharacters);
    export const getMovie = createSelector(getMoviesState, state => state.selectedMovie);
    export const getCharacterMovies = createSelector(getMoviesState, state => state.selectedCharacterMovies);
    export const getCharacter = createSelector(getMoviesState, state => state.selectedCharacter);
    
    // export const getCurrentPage = createSelector(getMoviesState, state => state.page);
    // export const getIsFirstPage = createSelector(getMoviesState, state => !state.previous);
    // export const getIsLastPage = createSelector(getMoviesState, state => !state.next);
    
    


    앱 내부에 캐릭터와 영화 구성 요소를 생성합니다(github에서 코드를 찾을 수 있음). 이 기사에서는 ngrx 부분을 보여주고 싶습니다. 다음 단계는 movies.effects.ts를 생성하는 것입니다.

    import { Injectable } from '@angular/core';
    import { Actions, createEffect, ofType } from '@ngrx/effects';
    import { Store } from '@ngrx/store';
    // import { getCurrentPage } from '../reducers/index';
    import { State } from './movies.reducer';
    import { MovieService } from './movie.service';
    import {
      MoviesActionTypes,
      MoviesActions,
      FetchMovies,
      FetchMoviesSuccess,
      FetchMoviesError,
      FetchMovieCharactersSuccess,
      FetchMovieCharactersError,
      FetchMovieError,
      FetchMovieSuccess,
      FetchCharacterError,
      FetchCharacterSuccess,
      FetchCharacterMoviesSuccess,
      FetchCharacterMoviesError
    } from './movies.actions';
    import { Observable, of } from 'rxjs';
    import { map, switchMap, catchError, withLatestFrom } from 'rxjs/operators';
    import { CharactersService } from '../characters/characters.service';
    import { Movie } from './models/movie';
    
    @Injectable()
    export class MoviesEffects {
    
      fetch$ = createEffect(() => {
        return this.actions$
          .pipe(
            ofType(MoviesActionTypes.FetchMovies),
            withLatestFrom(this.store),
            switchMap(([action, state]) =>
              this.service.getMovies().pipe(
                map(data => new FetchMoviesSuccess(data)),
                catchError(err => of(new FetchMoviesError(err)))
              )
            )
          )
      });
      fetchCharacters$ = createEffect(() => {
        return this.actions$
          .pipe(
            ofType(MoviesActionTypes.FetchMovieCharacters),
            withLatestFrom(this.store),
            switchMap(([action, state]) =>
    
              this.charactersService.getCharactersByFilm(this.service.selectedFilm).pipe(
                catchError(err => of(new FetchMovieCharactersError(err))),
                map(data =>
    
                  new FetchMovieCharactersSuccess(data)
                  // (characters: Movie['charactersData']) => {
                  // console.log("characters:", characters);
                  // // this.movieService.selectedFilm.charactersData=[];
                  // console.log("this.movieService.selectedFilm.charactersData:", this.movieService.selectedFilm.charactersData);
    
    
                  // //  this.movieService.selectedFilm.charactersData = characters;
                  // return true;
                  // }
                )
              )
            ))
      });
    
      fetchCharacterMovies$ =  createEffect(() => {
        return this.actions$
          .pipe(
            ofType(MoviesActionTypes.FetchCharacterMovies),
            withLatestFrom(this.store),
            switchMap(([action, state]) =>
    
              this.service.getFilmsByCharacter(this.service.selectedCharacter).pipe(
                catchError(err => of(new FetchCharacterMoviesError(err))),
                map(data =>
    
                  new FetchCharacterMoviesSuccess(data)
                  // (characters: Movie['charactersData']) => {
                  // console.log("characters:", characters);
                  // // this.movieService.selectedFilm.charactersData=[];
                  // console.log("this.movieService.selectedFilm.charactersData:", this.movieService.selectedFilm.charactersData);
    
    
                  // //  this.movieService.selectedFilm.charactersData = characters;
                  // return true;
                  // }
                )
              )
            ))
      });
    
      fetchMovie$ = createEffect(() => {
        return this.actions$
          .pipe(
            ofType(MoviesActionTypes.FetchMovie),
            withLatestFrom(this.store),
            switchMap(([action, state]) =>
              this.service.getFilm(this.service.selectedFilm.id).pipe(
                catchError(err => of(new FetchMovieError(err))),
                map(data =>
    
                  new FetchMovieSuccess(data)
                  // (characters: Movie['charactersData']) => {
                  // console.log("characters:", characters);
                  // // this.movieService.selectedFilm.charactersData=[];
                  // console.log("this.movieService.selectedFilm.charactersData:", this.movieService.selectedFilm.charactersData);
    
    
                  // //  this.movieService.selectedFilm.charactersData = characters;
                  // return true;
                  // }
                )
              )
            ))
      });
      // this.service.getMovies().pipe(
      //   map(data =>
      //     new FetchMovieCharactersSuccess(data)
      //   ),
      //   catchError(err => of(new FetchMovieCharactersError(err)))
      // )
      //   )
      // );
      fetchCharacter$ = createEffect(() => {
        return this.actions$
          .pipe(
            ofType(MoviesActionTypes.FetchCharacter),
            withLatestFrom(this.store),
            switchMap(([action, state]) =>
              this.charactersService.getCharacter(this.service.selectedCharacter.id).pipe(
                catchError(err => of(new FetchCharacterError(err))),
                map(data =>
    
                  new FetchCharacterSuccess(data)
                )
              )
            ))
      });
      paginate$ = createEffect(() => {
        return this.actions$
          .pipe(
            ofType(MoviesActionTypes.ChangePage),
            map(() => new FetchMovies())
          )
      });
    
      constructor(private actions$: Actions,
        private store: Store<State>,
        private service: MovieService,
        private charactersService: CharactersService) { }
    }
    
    


    createEffect 함수를 사용합니다(Observable 및 EffectConfig에서 효과 생성).

    movie.reducer.ts의 경우 아래 코드를 사용합니다.

    import { Action } from '@ngrx/store';
    import { MoviesActions, MoviesActionTypes, Pagination } from './movies.actions';
    import { Movie } from './models/movie';
    import { HttpErrorResponse } from '@angular/common/http';
    import { Character } from '../characters/models/character';
    
    export interface State {
      isLoading: boolean;
      error: HttpErrorResponse | null;
      data: Movie[] | null;
      selectedMovieCharacters: [] | null;
      selectedMovie:Movie| null;
      selectedCharacterMovies: [] | null;
      selectedCharacter: Character | null;
    
      // next: string | null;
      // previous: string | null;
    
    }
    
    export const initialState: State = {
      isLoading: false,
      error: null,
      data: [],
      selectedMovieCharacters:[],
      selectedMovie: null,
    
      selectedCharacter: null,
      selectedCharacterMovies:[]
    
    
      // next: null,
      // previous: null,
    
    };
    
    export function reducer(state = initialState, action: MoviesActions): State {
      switch (action.type) {
    
        case MoviesActionTypes.FetchMovies:
          return {
            ...state,
            isLoading: true,
            error: null
          };
    
        case MoviesActionTypes.FetchMoviesSuccess:
          return {
            ...state,
            isLoading: false,
            data: action.payload,
            // next: action.payload.next,
            // previous: action.payload.previous
          };
    
        case MoviesActionTypes.FetchMoviesError:
          return {
            ...state,
            isLoading: false,
            error: action.payload
          };
          case MoviesActionTypes.FetchMovie:
            return {
              ...state,
              isLoading: true,
              error: null
            };
    
          case MoviesActionTypes.FetchMovieSuccess:
            return {
              ...state,
              isLoading: false,
              selectedMovie: action.payload,
              // next: action.payload.next,
              // previous: action.payload.previous
            };
    
          case MoviesActionTypes.FetchMovieError:
            return {
              ...state,
              isLoading: false,
              error: action.payload
            };
    
        case MoviesActionTypes.FetchCharacter:
          return {
            ...state,
            isLoading: true,
            error: null
          };
    
        case MoviesActionTypes.FetchCharacterSuccess:
          return {
            ...state,
            isLoading: false,
            selectedCharacter: action.payload,
            // next: action.payload.next,
            // previous: action.payload.previous
          };
    
        case MoviesActionTypes.FetchCharacterError:
          return {
            ...state,
            isLoading: false,
            error: action.payload
          };
    
        case MoviesActionTypes.FetchCharacterMovies:
          return {
            ...state,
            isLoading: true,
            error: null
          };
    
        case MoviesActionTypes.FetchCharacterMoviesSuccess:
          return {
            ...state,
            isLoading: false,
            selectedCharacterMovies: action.payload,
            // next: action.payload.next,
            // previous: action.payload.previous
          };
    
        case MoviesActionTypes.FetchCharacterMoviesError:
          return {
            ...state,
            isLoading: false,
            error: action.payload
          };
    
        case MoviesActionTypes.FetchMovieCharacters:
          return {
            ...state,
            isLoading: true,
            error: null
          };
    
        case MoviesActionTypes.FetchMovieCharactersSuccess:
          return {
            ...state,
            isLoading: false,
            selectedMovieCharacters: action.payload,
            // next: action.payload.next,
            // previous: action.payload.previous
          };
    
    
        case MoviesActionTypes.FetchMovieCharactersError:
          return {
            ...state,
            isLoading: false,
            error: action.payload
          };
    
        // case MoviesActionTypes.ChangePage:
        //   return {
        //     ...state,
        //     page: action.payload === Pagination.NEXT ? ++state.page : --state.page
        //   };
    
        default:
          return state;
      }
    }
    


    우리는 movie.action.ts를 만들 것입니다

    import { Action } from '@ngrx/store';
    import { Movie, MoviesResponse } from './models/movie';
    import { HttpErrorResponse } from '@angular/common/http';
    
    export const enum MoviesActionTypes {
    
      FetchMovies = '[Movies] Fetch Movies',
      FetchMoviesSuccess = '[Movies] Load Movies Success',
      FetchMoviesError = '[Movies] Load Movies Error',
    
      ChangePage = '[Movies] Change page',
      FetchMovieCharacters = '[Movie] Fetch Movie Characters',
      FetchMovieCharactersSuccess = `[Movie] Load Movie Characters Success`,
      FetchMovieCharactersError = '[Movie] Load Movie Characters Error',
      FetchMovie = '[Movie] Fetch Movie ',
      FetchMovieSuccess = `[Movie] Load Movie Success`,
      FetchMovieError = '[Movie] Load Movie Error',
    
      FetchCharacter = '[Character] Fetch Character ',
      FetchCharacterSuccess = `[Character] Load Character Success`,
      FetchCharacterError = '[Character] Load Character Error',
    
      FetchCharacterMovies = '[Character] Fetch Character Movies ',
      FetchCharacterMoviesSuccess = `[Character] Load Character Movies Success`,
      FetchCharacterMoviesError = '[Character] Load Character Movies Error',
    
    }
    
    export const enum Pagination {
      NEXT,
      PREV
    }
    
    export class FetchMovies implements Action {
      readonly type = MoviesActionTypes.FetchMovies;
    }
    
    export class FetchMoviesSuccess implements Action {
      readonly type = MoviesActionTypes.FetchMoviesSuccess;
    
      constructor(public payload: Movie[]) { }
    }
    
    export class FetchMoviesError implements Action {
      readonly type = MoviesActionTypes.FetchMoviesError;
    
      constructor(public payload: HttpErrorResponse) { }
    }
    export class FetchMovie implements Action {
      readonly type = MoviesActionTypes.FetchMovie;
      constructor() {
        // console.log("*************FetchMovie*************");
    
      }
    }
    
    export class FetchCharacterSuccess implements Action {
      readonly type = MoviesActionTypes.FetchCharacterSuccess;
    
      constructor(public payload: any) {
        // console.log("FetchMovieSuccess");
    
      }
    }
    
    export class FetchCharacterError implements Action {
      readonly type = MoviesActionTypes.FetchCharacterError;
    
      constructor(public payload: HttpErrorResponse) { }
    }
    
    export class FetchCharacter implements Action {
      readonly type = MoviesActionTypes.FetchCharacter;
      constructor() {
        // console.log("*************FetchCharacter*************");
    
      }
    }
    export class FetchCharacterMoviesSuccess implements Action {
      readonly type = MoviesActionTypes.FetchCharacterMoviesSuccess;
    
      constructor(public payload: any) {
    
    
      }
    }
    
    export class FetchCharacterMoviesError implements Action {
      readonly type = MoviesActionTypes.FetchCharacterMoviesError;
    
      constructor(public payload: HttpErrorResponse) { }
    }
    
    export class FetchCharacterMovies implements Action {
      readonly type = MoviesActionTypes.FetchCharacterMovies;
      constructor() {
        // console.log("*************FetchCharacter*************");
    
      }
    }
    export class FetchMovieSuccess implements Action {
      readonly type = MoviesActionTypes.FetchMovieSuccess;
    
      constructor(public payload: any) {
        // console.log("FetchMovieSuccess");
    
      }
    }
    
    export class FetchMovieError implements Action {
      readonly type = MoviesActionTypes.FetchMovieError;
    
      constructor(public payload: HttpErrorResponse) { }
    }
    
    export class FetchMovieCharacters implements Action {
      readonly type = MoviesActionTypes.FetchMovieCharacters;
    }
    
    export class FetchMovieCharactersSuccess implements Action {
      readonly type = MoviesActionTypes.FetchMovieCharactersSuccess;
    
    
      constructor(public payload: any) {
        // console.log("FetchMovieCharactersSuccess");
      }
    }
    
    export class FetchMovieCharactersError implements Action {
      readonly type = MoviesActionTypes.FetchMovieCharactersError;
    
      constructor(public payload: HttpErrorResponse) { }
    }
    
    
    
    export class ChangePage implements Action {
      readonly type = MoviesActionTypes.ChangePage;
    
      constructor(public payload: Pagination) { }
    }
    
    export type MoviesActions = FetchMovieCharacters
      | FetchMovieCharactersSuccess
      | FetchMovieCharactersError
      | FetchMovies
      | FetchMoviesSuccess
      | FetchMoviesError
      | FetchMovie
      | FetchMovieSuccess
      | FetchMovieError
      | FetchCharacter
      | FetchCharacterSuccess
      | FetchCharacterError
      | FetchCharacterMovies
      | FetchCharacterMoviesSuccess
      | FetchCharacterMoviesError
      | ChangePage;
    
    


    영화 목록 구성 요소, 영화 세부 구성 요소 및 기타 캐릭터 구성 요소의 경우 이 githublink에서 전체 프로젝트를 찾을 수 있습니다.
    프로젝트를 실행하면 "스타워즈"영화 목록을 볼 수 있습니다.



    목록 앱에서 영화를 클릭하면 영화 세부 정보와 캐릭터 목록이 표시됩니다.



    캐릭터 이름 앱을 클릭하면 캐릭터 세부 정보 페이지로 이동하고 캐릭터 세부 정보와 캐릭터가 존재하는 영화 목록을 표시합니다.



    영화 이름을 클릭하면 영화 세부 정보 페이지로 이동합니다. 응용 프로그램은 ngrx 상태를 사용하여 영화 및 캐릭터와 관련된 모든 프로세스를 작업합니다.

    이 기사가 ngrx를 이해하는 데 도움이 되기를 바랍니다.

    좋은 웹페이지 즐겨찾기