Angular 17+NGRX 状态管理

angular 17 中使用了许多新feature, 比如standalone component,这带来了angular附属中间件比如状态管理中间件ngrx使用的改变。在翻阅ngrx文档后,发现即使最新版ngrx文档中仍然存在ngmodule与standalone写法的混合,容易造成使用者特别是最近版angluar 17 使用者的困惑。经过笔者实践,于是有的这篇博文用于简化说明在angular 17中ngrx的基本用法。

ngrx简单介绍

在angular中,实现状态管理可以使用service+observabel订阅,也可以使用第三方的NGRX。NGRX设计参考了react的redux,也由action,reducer等部分组成。

大概流程就是组件component中触发action事件,action事件调用对应的reducer函数,改变state/store状态。然后组件中可以通过selector订阅状态,拿到实时更新的共享信息。

安装ngrx

ng add @ngrx/store@latest

不要npm安装!!!否则引入报错没provider我也不知道为啥

ngrx实战

本文将通过实现用户登陆信息的状态管理的例子阐述ngrx基本用法。

本例创建了一个多属性状态的应用,可用于储存并获取某一实体类的不同属性信息。

1.创建action

创建两个action事件:set用于更新用户状态,reset用于清除用户状态

./store/action.ts

import { createAction,props} from "@ngrx/store";
import { StateType } from "./reducer";

export enum ActionTypes{
    Change='Change Data',
    Reset='Reset Data'
}


export const Set = createAction("Set Data",props< StateType>())
export const Reset = createAction("Reset Data")

2.创建reducer

创建reducer处理函数,分别处理set和reset事件

需要定义statetype状态接口,initialState初始状态

./store/reducer.ts

import { createReducer, on } from "@ngrx/store";
import { Set, Reset } from "./action";


export interface StateType{
    id:number,
    username:string,
    nickname:string
}

export const initialState:StateType={
    id:-1,
    username:"",
    nickname:""
}

export const userReducer = createReducer(
    initialState,
    on(Set, (state:StateType,action) =>{
        state={...action};
        return state;
    } ),
    on(Reset, (state) => initialState)
  )

3.在app.config.ts中注册reducer

在standalone模式中,引入中间件在app.config.ts中注册

provideState创建了名为state的feature状态(可以理解一个状态的副本,我也不知道为啥有state还要搞出一个feature的概念),使用userReducer进行管理。

import { provideStore,provideState } from '@ngrx/store';
import { userReducer } from './store/reducer';

export const appConfig: ApplicationConfig = {
  providers: [
    //inject ngrx
    provideStore(),
    provideState('user',userReducer)
]
};

4.创建selector

创建selector用于获取用户状态,注意createFeatureSelector()参数要与刚刚注册的feature名称对应

由于状态中有多个属性值(id,username,nickname),需要分别创建selector用于获取对应属性。否则在组件中拿到整个状态的observable对象不好分别获取对应属性

import { createFeatureSelector,createSelector } from "@ngrx/store";
import { StateType } from "./reducer";

export const selectUser=createFeatureSelector<StateType>('user');

export const selectUsername=createSelector(selectUser,(user:StateType)=>{
    return user.username;
})

export const selectNickname=createSelector(selectUser,(user:StateType)=>{
    return user.nickname;
})

export const selectId=createSelector(selectUser,(user:StateType)=>{
    return user.id;
})

5.在登陆组件中设置状态

在登陆组件中使用dispatch触发set处理函数,改变用户状态

./app/login/login.component.ts

import { Store } from '@ngrx/store';
import { Set } from '../store/action';
import { StateType } from '../store/reducer';

export class LoginComponent {
    onSubmit() {
        this.store.dispatch(Set(res.data));
    }

    constructor(
        private store:Store<UserState>  ) {}

}

6.在组件中获取状态

./app/header/header.component.ts:使用selector获取对应状态的属性值

import { Store } from '@ngrx/store';
import { StateType } from '../store/reducer';
import { selectUsername } from '../store/selector';
import { AsyncPipe} from '@angular/common';

@Component({
  selector: 'app-header',
  standalone: true,
  imports: [AsyncPipe],
  templateUrl: './header.component.html',
  styleUrl: './header.component.css'
})
export class HeaderComponent {
    username$=this.store.select(selectUsername);
    constructor(
    private store:Store<StateType>,
    ) { 
  }
}

./app/header/header.component.html:使用asyc管道读取observable对象

{{username$ | async}}

如有纰漏,敬请指出。

Reference:

https://next.ngrx.io/guide/store

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Angular是一个流行的JavaScript框架,用于构建Web应用程序。Ionic是基于Angular的开源移动应用开发框架,它提供了一套UI组件和具,帮助开发者构建跨平台的移动应用程序。 Swiper是一个流行的移动端滑动组件库,它提供了丰富的滑动效果和交互功能,可以用于创建漂亮的轮播图、图片浏览器等。 结合Angular和Ionic,你可以轻松地集成Swiper组件到你的移动应用中。首先,你需要在你的Angular项目中安装Swiper组件库。可以使用npm命令来安装: ``` npm install swiper --save``` 安装完成后,你可以在你的Ionic组件中引入Swiper组件,并在模板中使用它。以下是一个简单的示例: ```typescriptimport { Component } from '@angular/core'; import SwiperCore, { Navigation, Pagination } from 'swiper/core'; SwiperCore.use([Navigation, Pagination]); @Component({ selector: 'app-swiper', template: ` <swiper [navigation]="true" [pagination]="true"> <ng-template swiperSlide>Slide1</ng-template> <ng-template swiperSlide>Slide2</ng-template> <ng-template swiperSlide>Slide3</ng-template> </swiper> `, }) export class SwiperComponent {} ``` 在上面的示例中,我们首先引入了Swiper组件库,并注册了所需的Swiper模块(例如Navigation和Pagination)。然后,在组件的模板中,我们使用`<swiper>`标签创建了一个Swiper实例,并在内部添加了三个滑动的内容块。 你可以根据你的需求自定义Swiper的配置和样式。更多关于Swiper的用法和配置,你可以参考Swiper官方文档。 希望这可以帮助到你!如果你还有其他问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值