Javascript NgRX实体: ;ID在状态中未定义

Javascript NgRX实体: ;ID在状态中未定义,javascript,angular,rxjs,entity,ngrx,Javascript,Angular,Rxjs,Entity,Ngrx,我一直在一个虚拟的“Todo”项目中尝试@ngrx/entity,使用一个AppModule、一个reducer和一个组件。但是,我在尝试时遇到了一些问题 我的行动非常直接,只是一些积垢操作: import { Action } from '@ngrx/store'; import { Todo } from '../../models/todo'; export const CREATE = '[Todo] Create' export const UPDATE = '[Todo] Up

我一直在一个虚拟的“Todo”项目中尝试@ngrx/entity,使用一个AppModule、一个reducer和一个组件。但是,我在尝试时遇到了一些问题

我的行动非常直接,只是一些积垢操作:

import { Action } from '@ngrx/store';
import { Todo }  from '../../models/todo';


export const CREATE = '[Todo] Create'
export const UPDATE = '[Todo] Update'
export const DELETE = '[Todo] Delete'

export class Create implements Action {
    readonly type = CREATE;
    constructor(public todo: Todo) { }
}

export class Update implements Action {
    readonly type = UPDATE;
    constructor(
        public id: string,
        public changes: Partial<Todo>,
      ) { }
}

export class Delete implements Action {
    readonly type = DELETE;
    constructor(public id: string) { }
}

export type TodoActions
= Create
| Update
| Delete;
最后,在我的
app.component.ts
中,我只是尝试创建两个TODO:

import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';

import * as fromTodo from './reducers/todo.reducer';
import { Todo } from '../models/todo';
import { Create } from './reducers/todo.actions';


@Component({
    selector: 'app-root',
    template: `
    `,
    styles: []
})
export class AppComponent implements OnInit {

    public todos: Observable<Todo[]>;


    constructor(private store: Store<fromTodo.TodosState>) {
        this.store.dispatch(new Create({
            title: "Test todo",
            content: "This is a test todo",
            date: new Date()
        }))
        this.store.dispatch(new Create({
            title: "Test todo 2",
            content: "This is another todo",
            date: new Date()
        }))
    }

    ngOnInit() {
        this.todos = this.store.select(fromTodo.selectAll);
    }

}
从'@angular/core'导入{Component,OnInit};
从'@ngrx/Store'导入{Store};
从“rxjs/Observable”导入{Observable};
从“./reducers/todo.reducer”导入*作为从todo导入;
从“../models/Todo”导入{Todo};
从“./reducers/todo.actions”导入{Create};
@组成部分({
选择器:'应用程序根',
模板:`
`,
样式:[]
})
导出类AppComponent实现OnInit{
公共待办事项:可见;
构造函数(私有存储:存储){
this.store.dispatch(新建)({
标题:“测试待办事项”,
内容:“这是一个测试任务”,
日期:新日期()
}))
this.store.dispatch(新建)({
标题:“测试todo 2”,
内容:“这是另一个待办事项”,
日期:新日期()
}))
}
恩戈尼尼特(){
this.todos=this.store.select(fromTodo.selectAll);
}
}
但是,在运行这个之后,我检查了
Redux DevTools
。我看到它只创建第一个TODO,其id为“未定义”

My reducer中的My
console.log
显示
@ngrx/store/init
,以及这两个
[TODO]
创建操作


此外,如果我通过组件中的
todos
尝试
ngFor | async
,我会根据我的尝试得到各种错误(“主要是无法读取未定义的“map”属性)。

经过一些研究,我注意到
@ngrx/entity
使用了您使用的模型的
id
属性。 就我而言,我的
Todo
模型没有任何
id
属性,因此
@ngrx/entity
无法处理我的实体。 我以为它在内部生成ID,但显然没有

因此,解决此问题的方法是向模型中添加
id
属性,并在每次向状态中添加项目时自动生成该属性

例如,有一个模块

在我的例子中,我正在使用
ngrx
AngularFire2
,它有一个
createId()
方法:
const id=this.afs.createId()
。然后我可以将其添加到我想要添加的项目中,然后将其存储在我的Firestore数据库中

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';

import { AppComponent } from './app.component';
import { todoReducer } from './reducers/todo.reducer';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    StoreModule.forRoot({
      todo: todoReducer
    }),
    StoreDevtoolsModule.instrument({maxAge: 25}),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';

import * as fromTodo from './reducers/todo.reducer';
import { Todo } from '../models/todo';
import { Create } from './reducers/todo.actions';


@Component({
    selector: 'app-root',
    template: `
    `,
    styles: []
})
export class AppComponent implements OnInit {

    public todos: Observable<Todo[]>;


    constructor(private store: Store<fromTodo.TodosState>) {
        this.store.dispatch(new Create({
            title: "Test todo",
            content: "This is a test todo",
            date: new Date()
        }))
        this.store.dispatch(new Create({
            title: "Test todo 2",
            content: "This is another todo",
            date: new Date()
        }))
    }

    ngOnInit() {
        this.todos = this.store.select(fromTodo.selectAll);
    }

}