我正在尝试将我的 Ionic 应用程序转换为 NgRx。
在我的一个组件中,我有一个连接到文本区域的模型变量,如下所示:
组件:
myTextVar: string = '';
模板:
<ion-textarea ... [(ngModel)]="myTextVar" ...></ion-textarea>
因此,尝试将其转换为 NgRx,我在模块缩减器中创建了一个字段:
const textsFeatureKey = 'texts';
export interface TextsState {
...
myTextVar: string;
}
export const initialState: TextsState = {
...
myTextVar: '',
};
export const textsReducer = createReducer(
initialState,
...
on(TextsActions.setMyTextVar, (state, { myTextVar }) => ({ ...state, myTextVar })),
);
一个动作:
export const setMyTextVar = createAction('[Texts Page] Set myTextVar', props<{ myTextVar: string }>());
和选择器:
export const selectMyTextVar = (state: AppState) => state.texts.myTextVar;
然后在组件中我改变了这个:
myTextVar$: Observable<string>;
constructor(
private store: Store<{ texts: any; }>
) {
...
this.myTextVar$ = this.store.select(selectMyTextVar)
}
ngOnInit() {
this.myTextVar$.subscribe(text => {
console.log('mtv debug', text);
})
this.store.dispatch(setMyTextVar({ myTextVar: 'some initial text'}));
...
}
到目前为止一切顺利...当我这样做时,它在文本区域中加载了 myTextVar:
<ion-textarea [ngModel]="myTextVar$ | async" ></ion-textarea>
但是现在...我如何更新状态?我是这样做的:
<ion-textarea (ionInput)="onIonInputMyTextVar($event)" [ngModel]="myTextVar$ | async" ></ion-textarea>
然后在组件中:
onIonInputMyTextVar(event: any) {
this.store.dispatch(setMyTextVar({ myTextVar: event.detail.value }));
}
这有效。但这对于仅仅更新模型 var 来说是不是太牵强了?我用更大且更难维护的代码替换了 2 行代码,该代码必须处理 ionInput 事件、reducer、选择器、初始化、代码中的几个选择...
让我觉得我做错了什么。也许有一种更简单的方法来转换 ngModel 变量,或者只是我不应该使用 NgRx 来处理组件中的简单变量情况。
所以我的问题是:
[(ngModel)]='myTextVar'
不是更干净吗?您很困惑,因为您错过了关于 NGRX 存储的一件非常重要的事情:它用于 global 状态管理。 “全局”意味着至少在模块级别。
But isn't this too far fetched to just update a model var ? I have substituted 2 lines of code by a much larger and harder to maintain code having to handle ionInput event, reducer, selector, initialization, several selects along the code
看来你的情况就是这样。首先,您的组件看起来像一个“哑组件”,这意味着它根本不应该访问外部服务。其次,组件产生的值不会在任何地方使用,这意味着它不应该处于全局状态。第三,NGRX 是为大型应用程序创建的,而不是为任何类型的小型两组件大型副项目创建的。
在您决定将来使用任何类型的状态管理库之前,请考虑数据流:
当然,也有某些例外,但这是另一个话题了。