Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular NGXS,从同一个动作中调度启动、成功或失败动作的最佳方式?_Angular_Typescript_Asynchronous_Observable_Ngxs - Fatal编程技术网

Angular NGXS,从同一个动作中调度启动、成功或失败动作的最佳方式?

Angular NGXS,从同一个动作中调度启动、成功或失败动作的最佳方式?,angular,typescript,asynchronous,observable,ngxs,Angular,Typescript,Asynchronous,Observable,Ngxs,我有下面的代码来获取我所有的帖子 ` @Action(actions.FetchPosts) fetchAll(ctx: StateContext<PostStateModel>){ return this.postService.fetchPosts().pipe(tap((postsResults) => { const state = ctx.getState(); ctx.patchS

我有下面的代码来获取我所有的帖子

`    @Action(actions.FetchPosts)
    fetchAll(ctx: StateContext<PostStateModel>){
        return this.postService.fetchPosts().pipe(tap((postsResults) => {
            const state = ctx.getState();
                ctx.patchState({
                ...state,
                posts: [                    
                    ...postsResults                    
                ],                
            })
        }),
        mergeMap(() => {
          console.log("Inside of mergeMap")
          return ctx.dispatch(new actions.FetchPostsSuccess())
        }),      
        catchError(err => 
        {
          console.log("Inside of catchError")
          return ctx.dispatch(new actions.FetchPostsFail(err))
        }
      ))
    }`
`@Action(actions.FetchPosts)
fetchAll(ctx:StateContext){
返回此.postService.fetchPosts().pipe(点击((postsResults)=>{
const state=ctx.getState();
ctx.patchState({
……国家,
职位:[
…后结果
],                
})
}),
合并映射(()=>{
console.log(“mergeMap内部”)
返回ctx.dispatch(新操作.fetchPostsAccess())
}),      
catchError(err=>
{
console.log(“catchError内部”)
返回ctx.dispatch(新操作.FetchPostsFail(错误))
}
))
}`
这是可行的,但是,我想在调用我的邮政服务之前执行另一个调度。使用异步编程的最佳方法是什么,以确保我首先调度将loading属性设置为true的start操作,然后确保我仅在请求成功返回时调用success


另外,在ngxs文档之后,我使用了mergeMap(),它似乎完成了任务。不过我很好奇,返回一组帖子的postService是返回一个可观察的还是一个可观察的,然后会发出多个高阶可观察的(内部可观察的)?

您可以从分派加载操作开始:

@Action(actions.FetchPosts)
fetchAll(ctx: StateContext<PostStateModel>){
    return ctx.dispatch(new ChangeLoadingToInProgress()).pipe(
      mergeMap(() => this.postService.fetchPosts()),
      tap((postsResults) => {
        const state = ctx.getState();
            ctx.patchState({
            ...state,
            posts: [                    
                ...postsResults                    
            ],                
        })
    }),
    mergeMap(() => {
      console.log("Inside of mergeMap")
      return ctx.dispatch(new actions.FetchPostsSuccess())
    }),      
    catchError(err => 
    {
      console.log("Inside of catchError")
      return ctx.dispatch(new actions.FetchPostsFail(err))
    }
  ))
}
@Action(actions.FetchPosts)
fetchAll(ctx:StateContext){
返回ctx.dispatch(new ChangeLoadingToInProgress()).pipe(
mergeMap(()=>this.postService.fetchPosts()),
点击((postsResults)=>{
const state=ctx.getState();
ctx.patchState({
……国家,
职位:[
…后结果
],                
})
}),
合并映射(()=>{
console.log(“mergeMap内部”)
返回ctx.dispatch(新操作.fetchPostsAccess())
}),      
catchError(err=>
{
console.log(“catchError内部”)
返回ctx.dispatch(新操作.FetchPostsFail(错误))
}
))
}
或者我相信你可以马上改变现状:

@Action(actions.FetchPosts)
fetchAll(ctx: StateContext<PostStateModel>){
    ctx.patchState({ loading: true });
    return this.postService.fetchPosts().pipe(tap((postsResults) => {
        const state = ctx.getState();
            ctx.patchState({
            ...state,
            posts: [                    
                ...postsResults                    
            ],                
        })
    }),
    mergeMap(() => {
      console.log("Inside of mergeMap")
      return ctx.dispatch(new actions.FetchPostsSuccess())
    }),      
    catchError(err => 
    {
      console.log("Inside of catchError")
      return ctx.dispatch(new actions.FetchPostsFail(err))
    }
  ))
}
@Action(actions.FetchPosts)
fetchAll(ctx:StateContext){
patchState({loading:true});
返回此.postService.fetchPosts().pipe(点击((postsResults)=>{
const state=ctx.getState();
ctx.patchState({
……国家,
职位:[
…后结果
],                
})
}),
合并映射(()=>{
console.log(“mergeMap内部”)
返回ctx.dispatch(新操作.fetchPostsAccess())
}),      
catchError(err=>
{
console.log(“catchError内部”)
返回ctx.dispatch(新操作.FetchPostsFail(错误))
}
))
}

无需发送另一个操作即可将加载更新为true。您可以使用现有的FetchPost操作来更新状态。这两个答案都很有意义。我有第二个实现,但我不确定这样做是否正确。我想我必须做你在第一个例子中所做的。另外,我不应该同时使用switchMap吗?因为mergemap维护内部订阅,所以switchMap将只订阅内部可观察对象,直到发出新的可观察对象为止?因为我正在检索所有的帖子,所以我认为switchMap是我想要的两个帖子。你同意吗?@O.MeeKoh你说得对。绝对应该是地图。关于选择哪种方法,我实际上会选择第二种。但是,如果您希望有一个操作来切换加载状态,这实际上取决于您。我知道这会导致爆炸。另外,我不喜欢的是查看redux开发工具时的操作顺序——顺序不正确。这是有缺陷的,但目前我不认为创建一个单独的操作来切换isLoading状态有任何好处。@O.MeeKoh还有一件事——我个人会在
fetchpostsucess
处理程序中成功修补状态。
postResults
应该作为有效负载传递给操作。是的,这是一个很好的观点。我一定会实现这两个技巧。另外,你知道为什么它“肯定”是合并地图吗?我不确定我是否看到了完整的图片,因为我不太确定该使用哪一个。哦,等等,看起来这并不重要。不同之处在于switchMap取消订阅新emit上的内部可观测值。因为你总是在创建一个新的可观察对象,所以使用哪一个并不重要。但是,如果您将ngrx(您有ngxs)与
actions$.pipe(ofType(…)
一起使用,则新操作将使用switchMap取消旧操作。例如,如果您有一个重新加载按钮,并且您再次单击它,
mergeMap
将导致多个请求,
switchMap
将取消上一个请求。取决于你的用途。