Angular 如何从ngrx存储中的select获取错误?
假设我的商店可以使用一些操作:Load、LoadFail和LoadSuccess。我的所有操作都非常简单,Angular 如何从ngrx存储中的select获取错误?,angular,ngrx,Angular,Ngrx,假设我的商店可以使用一些操作:Load、LoadFail和LoadSuccess。我的所有操作都非常简单,LOAD=“LOAD”,LOAD\u FAIL=“LOAD failed”,以及LOAD\u SUCCESS=“LOAD SUCCESS”我有一个简单的减速器,可以打开这些减速器,如下所示: export function reducer(state: State = initialState, action: Actions): State { switch (action.typ
LOAD=“LOAD”
,LOAD\u FAIL=“LOAD failed”
,以及LOAD\u SUCCESS=“LOAD SUCCESS”
我有一个简单的减速器,可以打开这些减速器,如下所示:
export function reducer(state: State = initialState, action: Actions): State {
switch (action.type) {
case Actions.LOAD: {
console.log("Actions.LOAD");
return state;
}
case Actions.LOAD_FAIL: {
console.log("Actions.LOAD_FAIL");
store.error = action.payload;
return state;
}
case Actions.LOAD_SUCCESS: {
console.log("Actions.LOAD_SUCCESS");
state.data = action.payload;
return state;
}
default: {
return state;
}
}
}
我有一个处理负载分派的effects类:
@Injectable()
export class TestersEffects {
constructor(
private service: MyHttpService,
private actions$: Actions
) {}
@Effect() load$ = this.actions$.pipe(
ofType(Actions.LOAD),
switchMap(
action => {
return this.service.load().pipe(
map(data => {
console.log("load$ fired");
return new TestersActions.LoadSuccess(data);
}),
catchError(error => {
console.log("error");
return of (new Actions.LoadFail(error));
})
)
}
)
);
}
最后,我使用了所有这些:
export class MyClass implements OnInit {
data: any;
constructor(private store: Store<AppState>) {}
ngOnInit() {
this.store.dispatch(new Actions.Load());
this.store.select(store => store.State).subscribe(
data => this.data = data,
error => this.handleError(error)
);
}
handleError(error) {
//Whatever I'll do to handle this error
}
}
导出类MyClass实现OnInit{
资料:有;
构造函数(私有存储:存储){}
恩戈尼尼特(){
this.store.dispatch(new Actions.Load());
this.store.select(store=>store.State).subscribe(
data=>this.data=data,
error=>this.handleError(错误)
);
}
handleError(错误){
//不管我怎么处理这个错误
}
}
当我请求的服务器响应时,此代码工作正常。但是,我需要处理它没有响应的情况。我假设我对ngrx/store的流程理解得不够透彻,无法完全理解如何获取错误,但我不知所措。当我调试代码时,我的effects类中的catchError
会触发并发送LoadFail操作,reducer会捕获该操作,设置错误并返回状态。然而,在我订阅的MyClass
中,我从未看到任何东西。我想我一定错过了一些关键的东西,但我所有的谷歌专业知识让我两手空空,我想我应该勇敢地面对堆栈溢出,并在这件事上乞求它的智慧
tl;dr:当服务器响应时,我的商店工作正常,但当它没有响应时,我的错误没有被发送到商店状态可观察的订阅中。我认为您在这里遇到的问题是,您似乎试图将错误作为可观察链中的错误推送到商店中,而不是将错误作为您状态的另一部分 您所寻找的更像是:
//将属性添加到状态对象以保存错误。。。
界面状态{
// ...
错误:错误|空;
}
//然后在你的减速机里。。。
case Actions.LOAD\u失败:{
console.log(“Actions.LOAD_FAIL”);
返回{…状态,错误:action.error};
}
然后在您的订阅中,查询存储中此error
字段的值将让您知道请求是否失败以及是否发送了任何错误(我建议为此设置一个选择器,您可以直接订阅)
此外,我自己也没有尝试过,但我感觉,如果试图以这种方式对可观察到的存储进行错误操作,将会杀死应用程序中的存储,因此不应该尝试这样做。我找到了答案。我将把它放在类比中,然后从技术上加以解释 假设你有一辆车,和所有的车一样,有自己独特的VIN。在那辆车里,你有几个座位,人们可以坐。当汽车到达时,你只关心车内的人,而不一定关心汽车本身。从本质上讲,在我最初的例子中发生的事情是,我好像在检查它是否是一辆新车,而不是新来的人。所以为了让系统工作,我必须检查人,而不是车 所以它的技术性。比较两个对象时,如果它们的引用不相同,则无论它们包含的数据如何,它们都不是同一个对象。在我的例子中,我想观察我的状态对象的变化。这不起作用的原因是,尽管内部数据发生了变化,但状态对象的引用从未改变那么我是如何修复它的?嗯,有两种方法。如果要继续观察状态对象本身的更改,则需要在reducer中使用要提供的新数据重新分配它。否则,如果您只想观察更改/错误,则需要观察您关心的每个变量。 从本质上讲,这可以归结为:
interface Person {
name: string;
id: number;
}
function comparePeople() {
var p1: Person = { name: "John", id: 1 }
var p2: Person = { name: "James", id: 2 }
var p3: Person = { name: "John", id: 1 }
console.log(`p1 === p1 ? ${p1 === p1});
console.log(`p1 === p2 ? ${p1 === p2});
console.log(`p1 === p3 ? ${p1 === p3});
}
我在最初的帖子中没有提到这一点,但我确实尝试过类似的东西。也许是因为我的流动,我做错了。也许我需要处理效果中的成功和失败,然后返回一个包含错误的状态对象,而不是尝试使用两个单独的操作。我来试试看是否有效。谢谢你的意见。