无法从 store 获取值。

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

Store NGRX : can't get value from store

问题

以下是已翻译的内容:

AA.component.ts

chipSelected$: Observable<string>;

constructor(
  public emailService: EmailService,
  private store: Store<EmailState>
) {
  this.chipSelected$ = this.store.select('chipSelected').pipe(
    map((chipSelected: string) => {
      return chipSelected;
    })
  );
}

AA.component.html

{{chipSelected$ | async}}

BB.component.ts

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

email.state.ts

export const initialEmailState: EmailState = {
  chipSelected: 'oldValue',
};

export interface EmailState {
  chipSelected: 'oldValue' | 'newValue';
}

email.actions.ts

import { createAction, props } from '@ngrx/store';

export const changeChip = createAction(
  '[Email component] change chip selection',
  props<{ chipSelected: string }>()
);

email.reducer.ts

import { Action, createReducer, on } from '@ngrx/store';
import * as EmailAction from './email.actions';
import { EmailState, initialEmailState } from './email.state';

const changeChipReducer = (
  state: EmailState,
  action: ReturnType<typeof EmailAction.changeChip>
): EmailState => ({
  ...state,
  chipSelected: action.chipSelected,
});

export const emailReducer = createReducer(
  initialEmailState,
  on(EmailAction.changeChip, changeChipReducer)
);

在 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

 chipSelected$: Observable&lt;string&gt;;

  constructor(
    public emailService: EmailService,
    private store: Store&lt;EmailState&gt;
  ) {
    this.chipSelected$ = this.store.select(&#39;chipSelected&#39;).pipe(
      map((chipSelected: string) =&gt; {
        return chipSelected;
      })
    );
  }

AA.component.html

{{chipSelected$ | async}}

BB.component.ts

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

email.state.ts

export const initialEmailState: EmailState = {
  chipSelected: &#39;oldValue&#39;,
};

export interface EmailState {
  chipSelected: &#39;oldValue&#39; | &#39;newValue&#39;;
}

email.actions.ts

import { createAction, props } from &#39;@ngrx/store&#39;;

export const changeChip = createAction(
  &#39;[Email component] change chip selection&#39;,
  props&lt;{ chipSelected: string }&gt;()
);

email.reducer.ts

import { Action, createReducer, on } from &#39;@ngrx/store&#39;;
import * as EmailAction from &#39;./email.actions&#39;;
import { EmailState, initialEmailState } from &#39;./email.state&#39;;

const changeChipReducer = (
  state: EmailState,
  action: ReturnType&lt;typeof EmailAction.changeChip&gt;
): EmailState =&gt; ({
  ...state,
  chipSelected: action.chipSelected,
});

export const emailReducer = createReducer(
  initialEmailState,
  on(EmailAction.changeChip, changeChipReducer)
);

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 中定义:

// 存储中的某处
export interface AppState {
  email: EmailState;
}

// email.selectors.ts
export const selectEmail = (state: AppState) => state.email;
export const selectChip = createSelector(selectEmail, (email) => email.chipSelected);

然后,在你的组件中:

import * as EmailSelectors from 'myfolder/store/email/selectors/email.selectors';

ngOnInit(): void {
  // 不需要再进行管道操作,选择器已经返回你需要的内容
  // 请注意,我没有手动编写 "selectChip"
  this.chipSelected$ = this.store.select(EmailSelectors.selectChip);
}

有关 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:

// somewhere in the store
export interface AppState {
  email: EmailState;
}

// email.selectors.ts
export const selectEmail = (state: AppState) =&gt; state.email;
export const selectChip = createSelector(selectEmail, (email) =&gt; email.chipSelected);

Then, in your component:

import * as EmailSelectors from &#39;myfolder/store/email/selectors/email.selectors&#39;;

ngOnInit(): void {
  // don&#39;t need to pipe it, the selector already returns what you need
  // notice I didn&#39;t write manually &quot;selectChip&quot;
  this.chipSelected$ = this.store.select(EmailSelectors.selectChip);
}

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:

确定