我正在尝试使用 Angular 的独立 API 来实现 Ngrx,如下所示:
import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';
import { CartItem, Product } from '../types';
import { Observable, map, shareReplay } from 'rxjs';
import { Store } from '@ngrx/store';
@Component({
standalone: true,
imports: [
MatChipsModule,
CommonModule,
NgIf,
NgFor,
MatCardModule,
MatButtonModule,
],
selector: 'app-display',
templateUrl: './display.component.html',
styleUrls: ['./display.component.css'],
})
export class DisplayComponent implements OnInit {
products?: Product[];
cart$: Observable<CartItem[]>;
cartSize$: Observable<number>;
constructor(
private dataService: DataService,
private store: Store<{ cart: CartItem[] }>
) {
this.cart$ = this.store.select('cart');
this.cartSize$ = this.store.select('cart').pipe(
map((products: CartItem[]) =>
products.reduce((total, { quantity }) => total + quantity, 0)
),
shareReplay(1)
);
}
ngOnInit(): void {
this.getData();
}
getData() {
this.dataService
.getData()
.subscribe((products) => (this.products = products));
}
}
执行以下操作:
import { createAction, props } from '@ngrx/store';
import { CartItem, Product } from 'src/app/types';
export const addItem = createAction(
'[Cart Page] Add Item',
props<{ item: CartItem }>()
);
export const removeItem = createAction(
'[Cart Page] Remove Item',
props<{ productId: number }>()
);
export const updateItem = createAction(
'[Cart Page] Edit Item',
props<{ productId: number; quantity: number }>()
);
和减速机:
import { createReducer, on } from '@ngrx/store';
import { CartItem, Product } from 'src/app/types';
import { addItem, removeItem, updateItem } from './cart.actions';
export interface CartState {
cart: CartItem[];
error: string | null;
status: 'pending' | 'loading' | 'error' | 'success';
}
export const initialState: CartState = {
cart: [],
error: null,
status: 'pending',
};
export const cartReducer = createReducer(
initialState,
on(addItem, (state, { item }) => ({
...state,
cart: [...state.cart, { ...item }],
})),
on(removeItem, (state, { productId }) => ({
...state,
cart: state.cart.filter((_item) => _item.id !== productId),
})),
on(updateItem, (state, { productId, quantity }) => {
const updatedCart = state.cart.map((_item) => {
if (_item.id === productId) {
return { ..._item, quantity };
} else {
return _item;
}
});
return {
...state,
cart: updatedCart,
};
})
);
这是我的 main.ts 文件:
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { HttpClientModule } from '@angular/common/http';
import { importProvidersFrom } from '@angular/core';
import { StoreModule, provideStore } from '@ngrx/store';
import { cartReducer } from './app/state/cart/cart.reducer';
bootstrapApplication(AppComponent, {
providers: [
importProvidersFrom(
HttpClientModule,
StoreModule.forRoot({ cart: cartReducer })
),
],
});
但是我在以下代码中遇到此错误:
this.cartSize$ = this.store.select('cart').pipe(
map((products: CartItem[]) =>
products.reduce((total, { quantity }) => total + quantity, 0)
),
shareReplay(1)
);
错误显示:
ERROR TypeError: products.reduce is not a function
我在 html 中调用 cartSize$ 值,如下所示:
<h1>{{cartSize$ | async}}</h1>
没有值打印,甚至没有 0,所以我假设它是未定义的,尽管我不确定为什么它是未定义的。
您需要初始化数组,
products?: Product[] = [];