英文:
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<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>) {}
//Triggered when button clicked
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)
);
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('chipSelected')
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) => state.email;
export const selectChip = createSelector(selectEmail, (email) => email.chipSelected);
Then, in your component:
import * as EmailSelectors from 'myfolder/store/email/selectors/email.selectors';
ngOnInit(): void {
// don't need to pipe it, the selector already returns what you need
// notice I didn't write manually "selectChip"
this.chipSelected$ = this.store.select(EmailSelectors.selectChip);
}
For more information about selectors
, I recommend reading the docs
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论