簡體   English   中英

如何從ngrx存儲區中的select獲取錯誤?

[英]How to get errors from select in ngrx store?

假設我的商店可以使用一些操作:Load,LoadFail和LoadSuccess。 我所有的動作都非常簡單, LOAD = "load"LOAD_FAIL = "load failed"LOAD_SUCCESS = "load success"我有一個簡單的reducer可以打開這些,如下所示:

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;
        }
    }
}

我有一個處理負載分配的效果類:

@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
    }
}

當我請求的服務器響應時,此代碼可以正常工作。 但是,我需要處理它沒有響應的情況。 我假設我只是不太了解ngrx / store的流程,無法完全理解如何獲取錯誤,但是我很茫然。 當我調試代碼時,我的effects類中的catchError會觸發並發送一個LoadFail操作,Reducer會捕獲該操作,設置錯誤並返回狀態。 但是,在MyClass訂閱方面,我什么也看不到。 我認為我肯定在這里缺少一些關鍵的東西,但是我所有的Google搜尋專業知識都讓我無所事事,並且我想我會勇敢地利用Stack Overflow並乞求它在此問題上的智慧。

tl; dr:我的商店在服務器響應時工作正常,但在沒有響應時,我的錯誤並沒有發送到可觀察到的商店狀態訂閱。

我認為您在這里遇到的問題是,您似乎在嘗試將錯誤作為可觀察鏈中的錯誤推入整個商店,而不是使錯誤成為您狀態的另一部分。

您正在尋找的更像是:

// Add a property to your state object to hold errors...
interface State {
  // ...
  error: Error | null;
}

// Then in your reducer...
case Actions.LOAD_FAIL: {
  console.log("Actions.LOAD_FAIL");
  return { ...state, error: 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});
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM