Angular 13 具有 ngrx 效果从 Api 返回数据
Angular 13 with ngrx effects returning data from Api
我是 ngrx 的新手,我正在尝试 return 来自 api 调用的数据在我的效果中,但是我没有正确构建我的效果,我不知道如何更正它的效果。
所以首先,我有一个调用 Api:
的通用方法
export class CrudService {
//Rest Api
endpoint = 'http://localhost:4200';
constructor(private httpClient: HttpClient) { }
httpHeader = {
headers: new HttpHeaders({
'Content-Type': 'aplication/json'
})
}
getAll<T>(apiMethod: string): Observable<T> {
let callPoint = this.endpoint.concat('/', apiMethod);
return this.httpClient.get<T>(callPoint)
.pipe(
retry(1),
catchError(this.processError)
)
}.....
我的动作文件是:
import { Action } from '@ngrx/store';
import { Swivlr } from '../../Models/swivlr.model';
export const ADD_SWIVLR = '[SWIVLR] Add';
export const REMOVE_SWIVLR = '[SWIVLR] Remove';
export const GET_SWIVLR = '[SWIVLR] Get';
export const FAIL_SWIVLR = '[SWIVLR] Fail';
export class AddSwivlr implements Action {
public readonly type = ADD_SWIVLR;
constructor(public payload: Swivlr) { }
}
export class RemoveSwivlr implements Action {
public readonly type = REMOVE_SWIVLR;
constructor(public payload: number) { }
}
export class GetSwivlr implements Action {
public readonly type = GET_SWIVLR;
constructor(public payload: Swivlr[]) { }
}
export class FailSwivlr implements Action {
public readonly type = FAIL_SWIVLR;
constructor(public error: string | null) { }
}
export type Actions = AddSwivlr | RemoveSwivlr | GetSwivlr | FailSwivlr;
所以现在在我的效果文件中,我正在尝试编写获取所有记录的效果:
import { RemoveSwivlr, AddSwivlr, GetSwivlr, GET_SWIVLR, FAIL_SWIVLR, FailSwivlr } from '../Actions/swivlr.actions';
import { AppState } from '../../app/app.state';
import { CrudService } from '../crud/generic-crud';
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { catchError, map, Observable, of, switchMap } from 'rxjs';
import { Swivlr } from '../../Models/swivlr.model';
@Injectable()
export class SwivlrEffects {
constructor(private crudService: CrudService,
private readonly actions$: Actions
) { }
public readonly getSwivlr$: Observable<any> = createEffect(() => {
return this.actions$.pipe(ofType(GET_SWIVLR),
switchMap(() => of(this.crudService.getAll<Swivlr[]>('endpointAddress'))),
map((payload: Swivlr[]) => new GetSwivlr(payload)),
catchError((error: string | null) =>
of(new FailSwivlr(error)))
);
});
}
编译器不喜欢我的 switchMap 行,我希望这是因为我没有订阅我的 getAll 方法,我不确定在这种情况下我应该如何订阅。
我的模型已声明:
export interface Swivlr {
key: string;
name: string;
url: string;
width: string;
height: string;
}
任何关于我应该如何正确构建我的效果的帮助将不胜感激。
感谢@Deitsch,我将效果更改为:
public readonly getSwivlr$: Observable<any> = createEffect(() => {
return this.actions$.pipe(ofType(GET_SWIVLR),
mergeMap(() => this.crudService.getAll<Swivlr[]>('endpointAddress').pipe(
map((payload: Swivlr[]) => new GetSwivlr(payload)))),
catchError((error: string | null) =>
of(new FailSwivlr(error)))
);
});
您创建效果的语法错误。查看 ngrx.io/guide/effects 处的 movie.effects.ts
并将其用作起点。将 API 调用替换为您的调用,然后从那里开始。
getSwivlr$ = createEffect(() => {
return this.actions$.pipe(ofType(GET_SWIVLR), // use reference, not just same string!!
mergeMap(() => this.crudService.getAll<Swivlr[]>('endpointAddress').pipe(
map((payload) => new GetSwivlr(payload)))),
catchError((error) => of(new FailSwivlr(error)))
);
});
此外,您无需在任何地方手动添加输入。 Typescript 会为您正确处理它——如果有问题,它会告诉您。目前它非常混乱,实际上没有添加任何东西。
您也不应将 this.actions$.pipe(ofType(GET_SWIVLR)
中的类型 GET_SWIVLR
作为字符串引用 - 它很容易在您不注意的情况下中断。参考正确的操作类型!
在给定的 link 上,当您使用 switchMap 时会使用 mergeMap - 两者都有各自的用例,请阅读更多相关信息 blog.angular-university.io/rxjs-higher-order-mapping
另一件事是您创建的动作。它按照您的方式工作,但我建议您使用文档 ngrx.io/guide/store/actions
中的 createAction
方法
我是 ngrx 的新手,我正在尝试 return 来自 api 调用的数据在我的效果中,但是我没有正确构建我的效果,我不知道如何更正它的效果。
所以首先,我有一个调用 Api:
的通用方法export class CrudService {
//Rest Api
endpoint = 'http://localhost:4200';
constructor(private httpClient: HttpClient) { }
httpHeader = {
headers: new HttpHeaders({
'Content-Type': 'aplication/json'
})
}
getAll<T>(apiMethod: string): Observable<T> {
let callPoint = this.endpoint.concat('/', apiMethod);
return this.httpClient.get<T>(callPoint)
.pipe(
retry(1),
catchError(this.processError)
)
}.....
我的动作文件是:
import { Action } from '@ngrx/store';
import { Swivlr } from '../../Models/swivlr.model';
export const ADD_SWIVLR = '[SWIVLR] Add';
export const REMOVE_SWIVLR = '[SWIVLR] Remove';
export const GET_SWIVLR = '[SWIVLR] Get';
export const FAIL_SWIVLR = '[SWIVLR] Fail';
export class AddSwivlr implements Action {
public readonly type = ADD_SWIVLR;
constructor(public payload: Swivlr) { }
}
export class RemoveSwivlr implements Action {
public readonly type = REMOVE_SWIVLR;
constructor(public payload: number) { }
}
export class GetSwivlr implements Action {
public readonly type = GET_SWIVLR;
constructor(public payload: Swivlr[]) { }
}
export class FailSwivlr implements Action {
public readonly type = FAIL_SWIVLR;
constructor(public error: string | null) { }
}
export type Actions = AddSwivlr | RemoveSwivlr | GetSwivlr | FailSwivlr;
所以现在在我的效果文件中,我正在尝试编写获取所有记录的效果:
import { RemoveSwivlr, AddSwivlr, GetSwivlr, GET_SWIVLR, FAIL_SWIVLR, FailSwivlr } from '../Actions/swivlr.actions';
import { AppState } from '../../app/app.state';
import { CrudService } from '../crud/generic-crud';
import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { catchError, map, Observable, of, switchMap } from 'rxjs';
import { Swivlr } from '../../Models/swivlr.model';
@Injectable()
export class SwivlrEffects {
constructor(private crudService: CrudService,
private readonly actions$: Actions
) { }
public readonly getSwivlr$: Observable<any> = createEffect(() => {
return this.actions$.pipe(ofType(GET_SWIVLR),
switchMap(() => of(this.crudService.getAll<Swivlr[]>('endpointAddress'))),
map((payload: Swivlr[]) => new GetSwivlr(payload)),
catchError((error: string | null) =>
of(new FailSwivlr(error)))
);
});
}
编译器不喜欢我的 switchMap 行,我希望这是因为我没有订阅我的 getAll 方法,我不确定在这种情况下我应该如何订阅。
我的模型已声明:
export interface Swivlr {
key: string;
name: string;
url: string;
width: string;
height: string;
}
任何关于我应该如何正确构建我的效果的帮助将不胜感激。
感谢@Deitsch,我将效果更改为:
public readonly getSwivlr$: Observable<any> = createEffect(() => {
return this.actions$.pipe(ofType(GET_SWIVLR),
mergeMap(() => this.crudService.getAll<Swivlr[]>('endpointAddress').pipe(
map((payload: Swivlr[]) => new GetSwivlr(payload)))),
catchError((error: string | null) =>
of(new FailSwivlr(error)))
);
});
您创建效果的语法错误。查看 ngrx.io/guide/effects 处的 movie.effects.ts
并将其用作起点。将 API 调用替换为您的调用,然后从那里开始。
getSwivlr$ = createEffect(() => {
return this.actions$.pipe(ofType(GET_SWIVLR), // use reference, not just same string!!
mergeMap(() => this.crudService.getAll<Swivlr[]>('endpointAddress').pipe(
map((payload) => new GetSwivlr(payload)))),
catchError((error) => of(new FailSwivlr(error)))
);
});
此外,您无需在任何地方手动添加输入。 Typescript 会为您正确处理它——如果有问题,它会告诉您。目前它非常混乱,实际上没有添加任何东西。
您也不应将 this.actions$.pipe(ofType(GET_SWIVLR)
中的类型 GET_SWIVLR
作为字符串引用 - 它很容易在您不注意的情况下中断。参考正确的操作类型!
在给定的 link 上,当您使用 switchMap 时会使用 mergeMap - 两者都有各自的用例,请阅读更多相关信息 blog.angular-university.io/rxjs-higher-order-mapping
另一件事是您创建的动作。它按照您的方式工作,但我建议您使用文档 ngrx.io/guide/store/actions
中的createAction
方法