Angular NgRx 订阅状态导致未定义

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

我在 Angular 17 中设置了一个基本的 NgRx 示例。

这是我的 app.config.ts,我在商店中注册我的减速器

export const appConfig: ApplicationConfig = {
  providers: [provideRouter(routes), provideStore({ counterReducer} ), provideStoreDevtools({
    maxAge: 25, // Retains last 25 states
    logOnly: !isDevMode(), // Restrict extension to log-only mode
    autoPause: true, // Pauses recording actions and state changes when the extension window is not open
    trace: false, //  If set to true, will include stack trace for every dispatched action, so you can see it in trace tab jumping directly to that part of code
    traceLimit: 75, // maximum stack trace frames to be stored (in case trace option was provided as true)
  }),]
};

app.state.ts

export interface AppState {
  value: number;
}

计数器.reducer.ts

import { createReducer, on } from '@ngrx/store';
import { increment, decrement, reset } from './counter.actions';
import { AppState } from "./app.state";

export const initialState : AppState = {
  value: 0
};

export const counterReducer = createReducer(
  initialState,
  on(increment, (state) => ({ ...state, value: state.value + 1 })),
  on(decrement, (state) => ({ ...state, value: state.value - 1 })),
  on(reset, () => initialState)
);

export const selectCounterValue = (state: AppState) => state.value;

my-counter.component.html:这是我想显示我的状态的当前值的地方。我知道使用异步管道时我不必订阅计数。只是为了调试情况,我想打印到控制台

<button (click)="increment()">Increment</button>

<div>Current Count: {{ (count$ | async ) }}</div>

my-counter.component.ts 这是我想订阅我的 AppState.value 的地方。基本上我想在状态改变时打印出来。

import {Component, OnDestroy, OnInit} from '@angular/core';
import {Observable, Subscription} from 'rxjs';
import {Store} from "@ngrx/store";
import {increment} from "../store/counter.actions";
import {AppState} from "../store/app.state";
import {state} from "@angular/animations";
import {CommonModule} from "@angular/common";
import {selectCounterValue} from "../store/counter.reducer";

@Component({
  selector: 'app-my-counter',
  templateUrl: './my-counter.component.html',
  imports: [CommonModule],
  standalone: true,
})
export class MyCounterComponent implements OnInit, OnDestroy{
  count$: Observable<number>;
  subscription: Subscription | undefined;

  constructor(private store: Store<AppState>) {
    this.count$= store.select(selectCounterValue);
  }

  increment() {
    this.store.dispatch(increment());
  }

  ngOnInit(): void {
    this.subscription = this.count$.subscribe(value => {
      console.log(value);
    });
  }

  ngOnDestroy(): void {
    this.subscription?.unsubscribe();
  }

}

counter.reducer.ts:

import { createReducer, on } from '@ngrx/store';
import { increment, decrement, reset } from './counter.actions';
import { AppState } from "./app.state";

export const initialState : AppState = {
  value: 0
};

export const counterReducer = createReducer(
  initialState,
  on(increment, (state) => ({ ...state, value: state.value + 1 })),
  on(decrement, (state) => ({ ...state, value: state.value - 1 })),
  on(reset, () => initialState)
);

export const selectCounterValue = (state: AppState) => state.value;

如您所见,我的回调值的 console.log 未定义

但是,当单击我的增量按钮时,我的商店中的值会正确更新

我尝试像这样展示我的整个状态:

this.count$= store.select(state => state);

现在我在点击时总是得到一个值,但我只想获取该值而不是完整的状态

我错过了什么?我认为未定义与我的选择有关。基本上这是 https://ngrx.io/guide/store.

的示例
angular ngrx ngrx-store ngrx-store-4.0
1个回答
0
投票

问题似乎可能与您从商店中选择价值的方式有关。为了解决这个问题,请考虑利用 NgRx 库提供的

createSelector
函数。

此外,如果您的目标是简化流程并避免为各个状态手动创建选择器,您可能会发现 NgRx 的

createFeature
很有用。

您可以查看文档以了解它们的工作原理:
https://ngrx.io/api/store/createSelector
https://ngrx.io/api/store/createFeature

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