如何获取新项目NGRX的ID

时间:2018-08-05 23:16:16

标签: angular mongodb ngrx

我使用的格式是

{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的说明更新数据库 THEN 将返回的数据分派到商店

最后,我所做的是在do函数中进行了下一个方法调用,并将其添加到进行HTTP调用的效果中,因此使用服务器的响应来调用next方法。

我还设置了一种监听套接字的效果:

@Effect()watchSocket $ = this.socketService.socket $

通过套接字发送动作时,它会分派更新状态但现在具有正确有效负载的动作。

这是将websocket实施到ngrx的学习过程,例如,我最初是使用watchSocket $效果返回一个将进行HTTP调用的操作,然后调度一个操作以更新状态,

但是由于watchSocket $中的操作已分派给所有客户端,因此每个客户端都将尝试发出相同的HTTP请求,假设有100个客户端尝试删除同一项目!

所以我分成了两种效果来更新数据库(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)
            }
        })

1 个答案:

答案 0 :(得分:3)

因此,您有两个操作:

ADD_PRODUCT_REQUESTED(带有有效负载)

此处的有效负载是POST请求的主体(请参见下文)。 第一个动作触发一个效果,该效果向您的服务器发出后端POST(CREATE)请求。后端请求完成后,效果将触发下面的第二个动作,将响应作为有效负载传递。 (可选)该第一个操作可以将没有ID的数据插入到存储中,以便您可以开始显示数据而无需等待HTTP请求完成。

ADD_PRODUCT_COMPLETED(带有有效负载)

这将从效果中接收有效载荷,并将具有相关ID的数据插入(或更新)商店中的数据。

PS您可能还需要考虑使用ngrx / entity来简化集合的工作。

您可能习惯了采取行动和简化措施。如果您不熟悉ngrx / effects,这里有一些示例代码可以完成这种事情:

@Effect()
allFiltersRequested$ = this.actions$.pipe(
  ofType<BimRequestedAction>(BimsActionTypes.BimRequested),
  tap((action) => debug(action)),
  mergeMap((action) =>
    // essential to catchError else an HTTP error response will disable this effect
    this.bimService.getBim(action.payload).pipe(
      catchError(() => {
        return of({})
      })
    )
  ),
  map((bim) => new BimLoadedAction(bim))
)

bimService正在发出HTTP请求。

相关问题