我正在尝试学习NGRX商店,并且在模板中展示商店中的商品时遇到了一些问题。
商店似乎按预期工作。我发现当我发送一个动作时它会更新,所以当我想在这个例子中显示todo-list时,我认为我在组件中做错了。
模板:
<div *ngFor="let todo of (todoList$ | async)">Current Count: {{ todo.task }}</div>
<div>
<button (click)="addTodo()">Add</button>
</div>
TS:
import {Component} from '@angular/core';
import {Store} from '@ngrx/store';
import {Observable} from 'rxjs/Observable';
import * as TodoActions from './todo/store/todo.actions';
import {Todo} from './todo/todo.model';
import {State} from './todo/store/todo.reducers';
@Component({
selector: 'todo-list',
templateUrl: './todo-list.component.html'
})
export class TodoListComponent {
todoList$: Observable<Todo[]>;
constructor(private store: Store<State>) {
this.todoList$ = store.select('todos');
}
addTodo() {
this.store.dispatch(new TodoActions.AddTodo(new Todo('Finish todo-list', false)));
}
}
我在哪里做错了什么?
查看此stackblitz以获取完整的代码示例: https://stackblitz.com/edit/ngrx-test
谢谢!
答案 0 :(得分:1)
商店在添加Todo
方面确实有效,但未正确设置对商店的访问。
在您的app.module.ts
文件中,您的商店设置为StoreModule.forRoot({ todoList: todoReducer })
,这意味着您无法使用store.select('todos');
访问您的州。
您可以将此行放在构造函数中,就在store.select('todos');
行之前:
store.select(state => state).subscribe( val => console.log(val));
这应打印出{todoList: {todos:[...]}}
之类的内容,这意味着您无法通过State
选择访问store.select('todos');
。
您的代码需要进行一些更改。
首先,更改todoReducer
功能:
export function todoReducer(todos: Todo[] = initialState, action: TodoActions.TodoActions): Todo[] {
switch (action.type) {
case TodoActions.ADD_TODO:
console.log({
todos: [...todos, action.payload]
});
return [...todos, action.payload];
default:
return todos;
}
}
现在,此函数处理Todo
,而不是State
。
其次,我添加了类型tdReducer
的const值ActionReducerMap<State>
,如下所示:
export const tdReducer: ActionReducerMap<State> = {
todos: todoReducer
}
最后,我已将app.module.ts
文件中的条目更改为:
//rest of the imports
import * as red from './todo-list/todo/store/todo.reducers';
@NgModule({
imports: [
BrowserModule,
FormsModule,
StoreModule.forRoot(red.tdReducer)
],
//rest of the code
您可以在此link查看最终版本。
之前我没有使用过这个新版本的ngrx/store
,但您可以找到here解释的所有更改。