【发布时间】:2018-08-05 23:16:15
【问题描述】:
我使用的格式是
{product._id:{product._id:string, product_name:string}, product._id:{product._id:string, product_name:string}}
为我的商店保存产品信息
一切正常,加载时我设置了:
function handleBlogsLoadedAction(state, action) {
const returnedBlogs = action.payload
const blogObj = returnedBlogs.reduce(
(blogs: { [id: string]: Blog }, blog: Blog) =>
{
return Object.assign(blogs, { [blog._id]: blog });
}, {});
let newState = Object.assign({}, state);
newState = {
loaded:true,
blogs:blogObj
}
return newState;
}
所以我最终得到了类似的东西:
{"12345":{product._id:"12345", product_name:"product1"}, "6789":{product._id:"6789", product_name:"product2"}}
我有它更新和删除,但是在添加时,问题是在创建后获取 id 以便我可以插入状态的最佳方法
问题是我不想自己生成id,数据库必须自己做
有没有人知道最佳实践或只是对如何做到这一点有一些想法
编辑:
很抱歉,问题比上面说明的要复杂一些。
@danday74 的回答是正确的答案,但我的问题问得不好,我认为我应该分享和详细说明,希望能帮助到其他人。
我的商店也使用 websocket 与其他客户端通信,@Effect() beginUpdate$ 监听动作:
BLOG_UPDATE_START_ACTION, BLOG_DELETE_START_ACTION, BLOG_ADD_START_ACTION
当 beginUpdate$ 被触发时,为套接字主题调用下一个方法
this.socketService.socket$.next(JSON.stringify(action))
它携带/发送动作到连接的客户端,然后从 beginUpdate$ 调度一个动作来更新数据库。
你可以在这里看到问题,我需要更新数据库,正如@danday74所说那么将返回的数据发送到商店
所以我最终所做的是在 do 函数中调用 next 方法,并将其添加到进行 HTTP 调用的效果中,因此使用来自服务器的响应调用 next 方法
我也设置了监听socket的效果:
@Effect() watchSocket$ = this.socketService.socket$
当通过套接字发送操作时,它会分派更新状态的操作,但现在具有正确的有效负载。
在ngrx中实现websocket是一个学习曲线,例如,我最初使用watchSocket$效果来返回一个会进行HTTP调用的动作,然后调度一个动作来更新状态,
但是由于来自 watchSocket$ 的操作被分派给所有客户端,每个客户端都会尝试发出相同的 HTTP 请求,想象一下有 100 个客户端尝试删除相同的项目!
所以我分成2个效果一个来更新数据库(HTTP请求)
将响应发送到套接字,更新所有连接的存储。
如果有人可以就最佳做法提出任何建议,请随时
//Effects that make HTTP requests
@Effect({dispatch:false}) updateDB$: Observable<any> = this.actions$
.ofType<fromBlogActions.BlogUpdateDBAction>(fromBlogActions.BLOG_UPDATE_DB_ACTION)
.mergeMap(action => {
console.log(action)
return this.blogService.updateBlog(action.payload.blog)
})
.do((blog:Blog)=> this.socketService.socket$.next(JSON.stringify({type:fromBlogActions.BLOG_UPDATE_START_ACTION, payload:{blog:blog}})))
@Effect({dispatch:false}) deleteBlogFromDB$: Observable<any> = this.actions$
.ofType<fromBlogActions.BlogDeleteDBAction>(fromBlogActions.BLOG_DELETE_DB_ACTION)
.mergeMap(action => {
console.log(action)
return this.blogService.deleteBlog(action.payload.blog)
})
.do((blog:Blog)=> this.socketService.socket$.next(JSON.stringify({type:fromBlogActions.BLOG_DELETE_START_ACTION, payload:{blog:blog}})))
@Effect({dispatch:false}) addBlogToDB$: Observable<any> = this.actions$
.ofType<fromBlogActions.BlogAddToDBAction>(fromBlogActions.BLOG_ADDED_TO_DB_ACTION)
.mergeMap(action => {
console.log(action)
return this.blogService.addBlog(action.payload.blog)
.catch(()=>{
return Observable.of({})
})
})
.do((blog:Blog)=> this.socketService.socket$.next(JSON.stringify({type:fromBlogActions.BLOG_ADD_START_ACTION, payload:{blog:blog}})))
// Effects to update state
@Effect() deleteBlog$: Observable<any> = this.actions$
.ofType<fromBlogActions.BlogDeletedAction>(fromBlogActions.BLOG_DELETED_ACTION)
.map((action)=>new fromBlogUIActions.CrudSucessAction(action))
@Effect() updateBlog$: Observable<any> = this.actions$
.ofType<fromBlogActions.BlogUpdatedAction>(fromBlogActions.BLOG_UPDATED_ACTION)
.map((action)=>new fromBlogUIActions.CrudSucessAction(action))
@Effect() addBlog$: Observable<any> = this.actions$
.ofType<fromBlogActions.BlogAddedAction>(fromBlogActions.BLOG_ADDED_ACTION)
.map((action)=>new fromBlogUIActions.CrudSucessAction(action))
// Updates Database (CRUD)
@Effect() beginUpdate$: Observable<Action> = this.actions$
.ofType(fromBlogActions.BLOG_UPDATE_START_ACTION, fromBlogActions.BLOG_DELETE_START_ACTION, fromBlogActions.BLOG_ADD_START_ACTION)
.map((action:any)=>{
//Update database, but doing it here makes sure it's only done once
if (action.type === fromBlogActions.BLOG_UPDATE_START_ACTION) {
return new fromBlogActions.BlogUpdateDBAction(action.payload);
}
if (action.type === fromBlogActions.BLOG_DELETE_START_ACTION) {
return new fromBlogActions.BlogDeleteDBAction(action.payload);
}
if (action.type === fromBlogActions.BLOG_ADD_START_ACTION) {
return new fromBlogActions.BlogAddToDBAction(action.payload);
}
})
// Watches websocket
@Effect() watchSocket$:Observable<any> = this.socketService.socket$
.map((action : any) => {
//Update state across clients
if (action.type === fromBlogActions.BLOG_UPDATE_START_ACTION) {
return new fromBlogActions.BlogUpdatedAction(action.payload)
}
if (action.type === fromBlogActions.BLOG_DELETE_START_ACTION) {
return new fromBlogActions.BlogDeletedAction(action.payload)
}
if (action.type === fromBlogActions.BLOG_ADD_START_ACTION) {
return new fromBlogActions.BlogAddedAction(action.payload)
}
})
【问题讨论】:
-
通过 ADD_PRODUCT 和 ADD_PRODUCT_SUCCESS 等两个操作使用ngrx 效果,从服务器返回插入的对象,然后将其添加到存储中。