无法从 store 获取值。

huangapple go评论102阅读模式
英文:

Store NGRX : can't get value from store

问题

以下是已翻译的内容:

AA.component.ts

  1. chipSelected$: Observable<string>;
  2. constructor(
  3. public emailService: EmailService,
  4. private store: Store<EmailState>
  5. ) {
  6. this.chipSelected$ = this.store.select('chipSelected').pipe(
  7. map((chipSelected: string) => {
  8. return chipSelected;
  9. })
  10. );
  11. }

AA.component.html

  1. {{chipSelected$ | async}}

BB.component.ts

  1. constructor(private store: Store<EmailState>) {}
  2. // 当按钮被点击时触发
  3. setChip(): void {
  4. console.log("button clicked!");
  5. this.store.dispatch(changeChip({ chipSelected: 'newValue' }));
  6. }

email.state.ts

  1. export const initialEmailState: EmailState = {
  2. chipSelected: 'oldValue',
  3. };
  4. export interface EmailState {
  5. chipSelected: 'oldValue' | 'newValue';
  6. }

email.actions.ts

  1. import { createAction, props } from '@ngrx/store';
  2. export const changeChip = createAction(
  3. '[Email component] change chip selection',
  4. props<{ chipSelected: string }>()
  5. );

email.reducer.ts

  1. import { Action, createReducer, on } from '@ngrx/store';
  2. import * as EmailAction from './email.actions';
  3. import { EmailState, initialEmailState } from './email.state';
  4. const changeChipReducer = (
  5. state: EmailState,
  6. action: ReturnType<typeof EmailAction.changeChip>
  7. ): EmailState => ({
  8. ...state,
  9. chipSelected: action.chipSelected,
  10. });
  11. export const emailReducer = createReducer(
  12. initialEmailState,
  13. on(EmailAction.changeChip, changeChipReducer)
  14. );

在 app.module.ts 中(在该文件中导入了 EmailModule)
StoreModule.forRoot({ root: emailReducer })

希望这对你有所帮助。

英文:

I am currently doing a basic NGRX store.

I want a value in my Store (value called chipSelected: string), display that value in AA.component.ts and change it in BB.component.ts (through a button).

So I want my value displayed in AA.Component.ts initialized with my state initialState, and when I change it in BB.component.ts (through a button), my display var should be changed to.

This is currently what I have :

AA.component.ts

  1. chipSelected$: Observable&lt;string&gt;;
  2. constructor(
  3. public emailService: EmailService,
  4. private store: Store&lt;EmailState&gt;
  5. ) {
  6. this.chipSelected$ = this.store.select(&#39;chipSelected&#39;).pipe(
  7. map((chipSelected: string) =&gt; {
  8. return chipSelected;
  9. })
  10. );
  11. }

AA.component.html

{{chipSelected$ | async}}

BB.component.ts

  1. constructor(private store: Store&lt;EmailState&gt;) {}
  2. //Triggered when button clicked
  3. setChip(): void {
  4. console.log(&quot;button clicked!&quot;)
  5. this.store.dispatch(changeChip({ chipSelected: &#39;newValue&#39; }));
  6. }

email.state.ts

  1. export const initialEmailState: EmailState = {
  2. chipSelected: &#39;oldValue&#39;,
  3. };
  4. export interface EmailState {
  5. chipSelected: &#39;oldValue&#39; | &#39;newValue&#39;;
  6. }

email.actions.ts

  1. import { createAction, props } from &#39;@ngrx/store&#39;;
  2. export const changeChip = createAction(
  3. &#39;[Email component] change chip selection&#39;,
  4. props&lt;{ chipSelected: string }&gt;()
  5. );

email.reducer.ts

  1. import { Action, createReducer, on } from &#39;@ngrx/store&#39;;
  2. import * as EmailAction from &#39;./email.actions&#39;;
  3. import { EmailState, initialEmailState } from &#39;./email.state&#39;;
  4. const changeChipReducer = (
  5. state: EmailState,
  6. action: ReturnType&lt;typeof EmailAction.changeChip&gt;
  7. ): EmailState =&gt; ({
  8. ...state,
  9. chipSelected: action.chipSelected,
  10. });
  11. export const emailReducer = createReducer(
  12. initialEmailState,
  13. on(EmailAction.changeChip, changeChipReducer)
  14. );

In app.module.ts (in which I import my EmailModule)
StoreModule.forRoot({ root: emailReducer }),

In my console, I have "Button clicked" printed.
But on my view, I have not "oldValue" where I display my Observable, nor "newValue" when I click on the button. I have nothing displayed :'(

I don't see the action pass in my Redux Devtools, so I don't think it passed...

Like if my store and my component are not well declared... ?

Thank you very much for your help !

答案1

得分: 0

总体而言,你发布的代码看起来不错,唯一缺少的是适当的 selector。你使用了 this.store.select('chipSelected'),但是,chipSelected 在哪里声明/定义呢?它应该在 Email 的 selectors 中定义:

  1. // 存储中的某处
  2. export interface AppState {
  3. email: EmailState;
  4. }
  5. // email.selectors.ts
  6. export const selectEmail = (state: AppState) => state.email;
  7. export const selectChip = createSelector(selectEmail, (email) => email.chipSelected);

然后,在你的组件中:

  1. import * as EmailSelectors from 'myfolder/store/email/selectors/email.selectors';
  2. ngOnInit(): void {
  3. // 不需要再进行管道操作,选择器已经返回你需要的内容
  4. // 请注意,我没有手动编写 "selectChip"
  5. this.chipSelected$ = this.store.select(EmailSelectors.selectChip);
  6. }

有关 selectors 的更多信息,我建议阅读文档

英文:

Overall, your code posted looks fine, the only thing missing is a proper selector. You have this.store.select(&#39;chipSelected&#39;) but, where is chipSelected declared/defined?, it should be in the Email selectors:

  1. // somewhere in the store
  2. export interface AppState {
  3. email: EmailState;
  4. }
  5. // email.selectors.ts
  6. export const selectEmail = (state: AppState) =&gt; state.email;
  7. export const selectChip = createSelector(selectEmail, (email) =&gt; email.chipSelected);

Then, in your component:

  1. import * as EmailSelectors from &#39;myfolder/store/email/selectors/email.selectors&#39;;
  2. ngOnInit(): void {
  3. // don&#39;t need to pipe it, the selector already returns what you need
  4. // notice I didn&#39;t write manually &quot;selectChip&quot;
  5. this.chipSelected$ = this.store.select(EmailSelectors.selectChip);
  6. }

For more information about selectors, I recommend reading the docs

huangapple
  • 本文由 发表于 2023年2月26日 22:55:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75572811.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定