Angular 如何从ngrx存储中的select获取错误?

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、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.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});
}

我在最初的帖子中没有提到这一点,但我确实尝试过类似的东西。也许是因为我的流动,我做错了。也许我需要处理效果中的成功和失败,然后返回一个包含错误的状态对象,而不是尝试使用两个单独的操作。我来试试看是否有效。谢谢你的意见。