尝试在我的项目中使用 NgRx 但在 this.store.select 方法中出现错误

问题描述 投票:0回答:1

我正在尝试学习 NgRx,但在“selectAllBookings”上收到此错误:

public allBookings = this.store.select(selectAllBookings);

  Overload 1 of 9, '(mapFn: (state: object) => Booking[]): Observable<Booking[]>', gave the following error.
    Argument of type 'MemoizedSelector<AppState, Booking[], (s1: BookingState) => Booking[]>' is not assignable to parameter of type '(state: object) => Booking[]'.
      Types of parameters 'state' and 'state' are incompatible.
        Property 'bookings' is missing in type '{}' but required in type 'AppState'.
  Overload 2 of 9, '(key: never): Observable<never>', gave the following error.
    Argument of type 'MemoizedSelector<AppState, Booking[], (s1: BookingState) => Booking[]>' is not assignable to parameter of type 'never'. [plugin angular-compiler]

    src/app/booking-table/booking-table.component.ts:14:41:
      14 │   public allBookings = this.store.select(selectAllBookings);
         ╵                                          ~~~~~~~~~~~~~~~~~

  'bookings' is declared here.

    src/app/store/app.state.ts:4:4:
      4 │     bookings: BookingState;

AppState.ts

import { BookingState } from "./booking.reducer";

export interface AppState {
    bookings: BookingState;
}

预订.action.ts

import { createAction, props } from "@ngrx/store";
import { Booking } from "../model/booking.model";

export const loadBookings = createAction(
    '[Booking API] Load bookings'
);

export const loadBookingsSuccess = createAction(
    '[Booking API] Booking Load Success',
    props<{ bookings: Booking[] }>()
);

预订.effects.ts

import { Injectable } from "@angular/core";
import { createEffect, ofType, Actions } from "@ngrx/effects";
import { map, switchMap, from } from "rxjs";
import { BookingService } from "../booking.service";
import * as BookingActions from "../store/booking.actions";
import { Store } from "@ngrx/store";
import { AppState } from "./app.state";

@Injectable()
export class BookingEffects {

    constructor(private actions$: Actions, private bookingService: BookingService, private store: Store<AppState>) {}

    loadBookings$ = createEffect(() => 
        this.actions$.pipe(
            ofType(BookingActions.loadBookings),
            switchMap(() => 
                from(this.bookingService.getBookings()).pipe(
                map((bookings) => BookingActions.loadBookingsSuccess({ bookings: bookings}))
                )
            )
        )
    )
}

预订.reducer.ts

import { createReducer, on } from "@ngrx/store";
import { Booking } from "../model/booking.model";
import { loadBookings, loadBookingsSuccess } from "./booking.actions";

export interface BookingState {
    bookings: Booking[];
    error: string;
    status: 'pending' | 'loading' | 'error' | 'success';
}

export const initialState: BookingState = {
    bookings: [],
    error: "",
    status: 'pending',
}

export const bookingReducer = createReducer(
    //Supply initial state
    initialState,
    //Trigger loading bookings
    on(loadBookings, (state) => ({ ...state, status: 'loading' as const })),
    on(loadBookingsSuccess, (state, { bookings }) => ({
        ...state,
        bookings: bookings,
        error: '',
        status: 'success' as const,
    }))
)

预订.selector.ts

import { createSelector } from "@ngrx/store";
import { AppState } from "./app.state";
import { BookingState } from "./booking.reducer";

export const selectBookings = (state: AppState) => state.bookings;
export const selectAllBookings = createSelector(
    selectBookings,
    (state: BookingState) => state.bookings
);

app.modules.ts

import { NgModule, isDevMode } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { EffectsModule } from '@ngrx/effects';
import { BookingTableComponent } from './booking-table/booking-table.component';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { HttpClientModule } from '@angular/common/http';
import { bookingReducer } from './store/booking.reducer';
import { BookingEffects } from './store/booking.effects';

@NgModule({
  declarations: [
    AppComponent,
    BookingTableComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    StoreModule.forRoot({ bookings: bookingReducer }, {}),
    StoreDevtoolsModule.instrument({ maxAge: 25, logOnly: !isDevMode() }),
    EffectsModule.forRoot([BookingEffects]),
    HttpClientModule
  ],
  providers: [
    provideAnimationsAsync()
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

预订.组件.ts

import { Component, OnInit } from '@angular/core';
import { BookingService } from '../booking.service';
import { loadBookings } from '../store/booking.actions';
import { Store } from '@ngrx/store';
import { Booking } from '../model/booking.model';
import { selectAllBookings } from '../store/booking.selector';

@Component({
  selector: 'app-booking-table',
  templateUrl: './booking-table.component.html',
  styleUrl: './booking-table.component.css'
})
export class BookingTableComponent implements OnInit {
  //Error here
  public allBookings = this.store.select(selectAllBookings);

  constructor(private store: Store) {

  }

  ngOnInit(): void {
    this.store.dispatch(loadBookings());
  }

}
angular typescript ngrx ngrx-store ngrx-effects
1个回答
0
投票

也许尝试获得这样的功能

export const selectBookings = createFeatureSelector<FeatureState>(featureKey);

使用

createFeatureSelector
而不是手动。 你的代码看起来不错 - 看起来像是直接来自文档,但错误似乎表明它期望以不同的方式传递不同的状态片段。 ngrx 内置的功能选择器可能会让他们高兴。 如此处文档中所述

© www.soinside.com 2019 - 2024. All rights reserved.