使用 ApiService 将 redux 工具包方法 createAsyncThunk 与 Angular HttpClient 集成

Posted

技术标签:

【中文标题】使用 ApiService 将 redux 工具包方法 createAsyncThunk 与 Angular HttpClient 集成【英文标题】:Integrate redux toolkit method createAsyncThunk with Angular HttpClient using ApiService 【发布时间】:2020-11-16 19:05:24 【问题描述】:

我正在尝试在 Angular 应用程序中实现 @reduxjs/toolkit

如何将 Angular 服务作为参数传递给 createAsyncThunk 的回调而不是使用 fetch

来自docs的示例

const fetchUserById = createAsyncThunk(
  'users/fetchById',
  async (userId: number) => 
    const response = await fetch(`https://reqres.in/api/users/$userId`)
    // replace fetch with apiService.fetchUserById(userId)
    return (await response.json()) as MyData
  
)

最终我想使用HttpClientModule 来获取数据。

编辑

这是我的方法,有没有更好的方法或更“Angular 的方法”来实现它?

// projects.slice.ts


export const INITIAL_STATE_PROJECTS: IProjectsState = 
    projectList: [],
;

export const fetchProjects = createAsyncThunk(
    'projects/fetchProjects',
    async (projectsService: ProjectsService) => 
        const response = await projectsService.getAllProjects();
        return response;
    
);

const projectsSlice = createSlice(
    name: 'projects',
    initialState: INITIAL_STATE_PROJECTS,
    reducers: 

    ,
    extraReducers: 
        [fetchProjects.fulfilled.toString()]: (state, action) => 
            state.projectList = action.payload;
        ,
    
);

export default projectsSlice.reducer;
// projects.service.ts


@Injectable(
    providedIn: 'root'
)
export class ProjectsService 
    private serverURL = environment.api_url;
    
    constructor(private http: HttpClient)  

    async getAllProjects(): Promise<IProject[]> 
        return new Promise((resolve, reject) => 
            const headers = new HttpHeaders();
            headers.append('Content-Type', 'application/json');
            this.http.get<IProject[]>(`$this.serverURL/projects`,  headers, withCredentials: true )
                .subscribe(async (res) => 
                    resolve(res);
                , (err) => 
                    reject(err);
                );
        );
    


// project-list.component.ts

@Component(
    selector: 'app-project-list',
    templateUrl: './project-list.component.html',
    styleUrls: ['./project-list.component.scss']
)
export class ProjectListComponent implements OnInit 
    @select((state: IAppState) => state.projects.projectList) readonly projects$: Observable<any[]>;

    constructor(
        private projectsService: ProjectsService,
        private ngRedux: NgRedux<IAppState>
    )  

    ngOnInit(): void 
        this.ngRedux.dispatch<any>(fetchProjects(this.projectsService));
    

【问题讨论】:

是什么阻碍了您只使用apiService.getUserById(userId) 我需要某种方式将 apiService 实例传递给回调,以便我可以调用 getUserById 为什么需要传递一个实例?服务在 Angular 中通常是单例,所以应该只有一个实例。 我的意思是单例实例。我很困惑,因为我在平面 ts 文件中实现了 redux,而其余的应用程序使用类。我没有办法注入服务,所以我想知道如何使用 HttpClient。 Redux 文档只考虑反应。 那你为什么要在纯js文件中做呢? 【参考方案1】:

我希望我理解正确 - 如果没有让我知道,但如果我知道了,你可以将它包装在一个封闭的函数中:

const fetchUserById = (apiService: ApiService, userId: numer) => 
    return createAsyncThunk(
        'users/fetchById',
        async (userId: number) => 
            const response = await apiService.getUserById(userId);
            return (await response.json()) as MyData
        
    )

现在你可以这样称呼它:

const user = fetchUserById(apiService, 1);

【讨论】:

这基本上是我想要的,但这不是解决方案,createAsyncThunk 需要分配给它没有返回的 fetchUserById。在进行更多研究后,我将使用更多信息编辑我的问题。我问的可能不是我的问题的解决方案。

以上是关于使用 ApiService 将 redux 工具包方法 createAsyncThunk 与 Angular HttpClient 集成的主要内容,如果未能解决你的问题,请参考以下文章

如何将 redux 与 graphql 一起使用

react-redux 工具包应用程序在尝试将 redux 数据导入组件时出现问题

Redux Toolkit:如何将使用 createAction 创建的操作作为类型引用

Redux Persist + Redux 工具包 $CombinedState 错误

更换 redux 工具包商店或其他方式拥有两个商店

Redux工具包 - Redux Toolkit的基本使用