假设您通过从BookComponent调度CREATE_BOOK操作来创建新Book。实际上,我们正在处理http保存,然后通过CREATE_BOOK_SUCCESS操作将创建的Book传递给减速器。到目前为止一切顺利。
但是,如何在生成CREATE_BOOK操作的BookComponent中获取新创建的Book的ID?我只能想到解决方法:
答案 0 :(得分:2)
您不能直接让组件知道已创建的ID,因为您必须遵循redux的单向数据流。
如果您真的想在某个地方使用ID,则可以按照您提到的方式将其存储在商店状态中,或者创建ID客户端。
如果要在列表中的某处突出显示已创建的书,则可以实现*ngFor
指令的trackBy
function,并在新创建的项目上创建动画。
有关更多效果的用法,请查看Start using ngrx/effects for this
答案 1 :(得分:2)
我也一直在面对这种情况,我认为您有2种选择:
生成ID并将其传递到操作的有效负载内(如果需要,还可以添加当前有效负载)。您可以将其命名为actionId
。
从您的效果来看,当您映射到动作CREATE_BOOK_SUCCESS
时,还要传递您有权访问的ID! (因为我们在处理CREATE_BOOK
动作的代码段中。)
从(智能)组件中,您可以订阅动作,就像在效果中一样!因此,您可以执行以下操作:
class MyComponent {
// ...
createBook(book: Book) {
// first, generate a unique ID to track the action
// you can call directly the uuid function or even better create
// a uuidService that you inject but for simplicity here I'm not doing it
const actionId: string = uuid();
// then watch for an action of type CREATE_BOOK_SUCCESS with that ID
this.actions.pipe(
ofType<BooksActions.CreateBookSuccess>(BooksActions.CREATE_BOOK_SUCCESS),
filter(({payload}) => payload.actionId === actionId),
first(),
tap(({payload}) => {
// do what you want here
// you've got access to the payload of the CREATE_BOOK_SUCCESS action where
// you have the book returned from the backend (I think)
})
);
// finally, dispatch the action
// it's important to do it after you've subscribed to actions otherwise it might happen
// too fast and you wouldn't get the notification
this.actions.dispatch(new BooksActions.CreateBook({ ...book, actionId }));
}
// ...
}
请注意,在订阅该操作时,我在这里使用first
,因此即使您快速地重新添加10本书,您也会有10个不同的订阅,这完全没问题。