Ngxs Store

agnusdei·2023년 7월 13일
0

import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import {
  provideRouter,
  withEnabledBlockingInitialNavigation,
} from '@angular/router';
import { appRoutes } from './app.routes';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { HttpInterceptorImpl } from './interceptors/http-interceptor'; // interceptor
import { NgxsModule } from '@ngxs/store'; // store
import { AdminStore } from './store/auth.store'; // store
import { IonicModule } from '@ionic/angular'; // ionic

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(appRoutes, withEnabledBlockingInitialNavigation()),
    importProvidersFrom(
      HttpClientModule,
      NgxsModule.forRoot([AdminStore]),
      IonicModule.forRoot()
    ),
    { provide: HTTP_INTERCEPTORS, useClass: HttpInterceptorImpl, multi: true },
  ],
};

app module 기본 설정

import { Injectable } from '@angular/core';
import { State, Action, StateContext, Selector, NgxsOnInit, Store } from '@ngxs/store';
import { ActivatedRoute, Router } from '@angular/router';
import { HttpService } from '../app/services/http.service';
import { IAuthDTO } from '@aresa/interface'

export class SetAuth {
    static readonly type = '[Auth] Set Auth';
    constructor(public auth: IAuthDTO) { }
}

export class ResetAuth {
    static readonly type = '[Auth] Reset Auth';
    constructor() { }
}

export type AuthStateModel = {
    auth: IAuthDTO | null
}

@State<AuthStateModel>({
    name: 'auth',
    defaults: {
        auth: {
            admin: null,
            user: null
        },
    }
})
@Injectable()
export class AuthState implements NgxsOnInit {

    constructor(
        private httpService: HttpService,
        private readonly store: Store,
        private router: Router,
        private route: ActivatedRoute
    ) { }

    ngxsOnInit(ctx: StateContext<any>): void {
        const accessToken = localStorage.getItem('ACCESS_TOKEN');
        if (accessToken) {
            this.httpService.get<IAuthDTO>('auth', { headers: { Authorization: `Bearer ${accessToken}` } }).subscribe({
                next: (auth) => {
                    ctx.setState({ auth });
                    this.store.dispatch(new SetAuth(auth));
                }
            })
        }
    }

    @Selector()
    static isAuthenticated(state: AuthStateModel): boolean {
        return !!state.auth
    }

    @Selector()
    static auth(state: AuthStateModel): IAuthDTO | null {
        return state.auth;
    }

    @Action(SetAuth)
    setAuth(ctx: StateContext<AuthStateModel>, action: SetAuth) {
        ctx.setState({
            auth: action.auth
        })
    }

    @Action(ResetAuth)
    resetAuth(ctx: StateContext<AuthStateModel>) {
        ctx.setState({
            auth: null
        })
    }
}

 @Select(AuthState) auth$!: Observable<IAuthDTO>;

해당 코드는 Angular 애플리케이션에서 사용되는 Ngxs(State Management)를 통해 인증 관련 상태를 관리하는 AuthState 클래스입니다. 코드를 하나씩 분석하고 주석으로 설명하겠습니다.

import { Injectable } from '@angular/core';
import { State, Action, StateContext, Selector, NgxsOnInit, Store } from '@ngxs/store';
import { ActivatedRoute, Router } from '@angular/router';
import { HttpService } from '../app/services/http.service';
import { IAuthDTO } from '@aresa/interface'
  • 위 코드는 필요한 Angular 및 Ngxs 모듈, 서비스, 인터페이스를 가져옵니다.
export class SetAuth {
    static readonly type = '[Auth] Set Auth';
    constructor(public auth: IAuthDTO) { }
}

export class ResetAuth {
    static readonly type = '[Auth] Reset Auth';
    constructor() { }
}
  • 위 코드는 Ngxs 액션 클래스를 정의합니다. SetAuthResetAuth 액션은 인증(auth)과 관련된 상태를 설정하고 재설정하는 데 사용됩니다.
export type AuthStateModel = {
    auth: IAuthDTO | null
}
  • AuthStateModel은 인증 상태(auth)의 모델을 정의합니다. auth 속성은 IAuthDTO 인터페이스 또는 null 값일 수 있습니다.
@State<AuthStateModel>({
    name: 'auth',
    defaults: {
        auth: {
            admin: null,
            user: null
        },
    }
})
@Injectable()
export class AuthState implements NgxsOnInit {
    // ...
}
  • 위 코드는 AuthState 클래스를 정의합니다. @State 데코레이터를 사용하여 Ngxs 상태로 등록됩니다.
  • name: 'auth'는 상태의 이름을 auth로 설정합니다.
  • defaults 속성은 초기 상태를 정의합니다. auth 속성은 adminusernull로 갖는 초기 인증 객체입니다.
  • @Injectable() 데코레이터는 의존성 주입을 위해 AuthState 클래스를 주입 가능한 서비스로 표시합니다.
constructor(
    private httpService: HttpService,
    private readonly store: Store,
    private router: Router,
    private route: ActivatedRoute
) { }
  • 위 코드는 AuthState 클래스의 생성자입니다. httpService, store, router, route 등의 의존성을 주입받습니다.
ngxsOnInit(ctx: StateContext<any>): void {
    const accessToken = localStorage.getItem('ACCESS_TOKEN');
    if (accessToken) {
        this.httpService.get<IAuthDTO>('auth', { headers: { Authorization: `Bearer ${accessToken}` } }).subscribe({
            next: (auth) => {
                ctx.setState({ auth });
                this.store.dispatch(new SetAuth(auth));
            }
        })
    }
}
  • NgxsOnInit 인터페이스를 구현하여 ngxsOnInit 메서드를 정의합니다. 이 메서드는 상태가 초기화될 때 실행됩니다.
  • ngxsOnInit 메서드는 localStorage에서 액세스 토큰을 가져와 인증 요청을 보내고, 응답으로 받은 인증 객체를 상태에 설정합니다. 또한 SetAuth 액션을 디스패치하여 상태 업데이트를 알립니다.
@Selector()
static isAuthenticated(state: AuthStateModel): boolean {
    return !!state.auth
}

@Selector()
static auth(state: AuthStateModel): IAuthDTO | null {
    return state.auth;
}
  • 위 코드는 @Selector() 데코레이터를 사용하여 선택자(selector) 메서드를 정의합니다.
  • isAuthenticated 선택자는 auth 상태가 존재하는지 여부를 불리언 값으로 반환합니다.
  • auth 선택자는 현재 인증(auth) 상태 객체를 반환합니다.
@Action(SetAuth)
setAuth(ctx: StateContext<AuthStateModel>, action: SetAuth) {
    ctx.setState({
        auth: action.auth
    })
}

@Action(ResetAuth)
resetAuth(ctx: StateContext<AuthStateModel>) {
    ctx.setState({
        auth: null
    })
}
  • 위 코드는 @Action() 데코레이터를 사용하여 액션 핸들러 메서드를 정의합니다.
  • setAuth 액션 핸들러는 인증 객체를 상태에 설정합니다.
  • resetAuth 액션 핸들러는 인증 객체를 null로 재설정합니다.
@Select(AuthState) auth$!: Observable<IAuthDTO>;
  • 위 코드는 @Select() 데코레이터를 사용하여 상태 선택자를 정의합니다. auth$AuthState 상태의 변화를 구독하는 Observable입니다.

코드는 Ngxs를 사용하여 인증 상태를 관리하기 위한 AuthState 클래스를 정의하고 있습니다. 이를 통해 애플리케이션에서 인증 상태를 추적하고 업데이트할 수 있으며, 선택자를 통해 현재 상태를 조회할 수 있습니다.

0개의 댓글