传说
action-chain epic=epic,根据服务调用返回“成功”或“失败”操作。
service=http服务,来自HttpModule,angular2
目标
我需要把数据发送到服务器。我有一个CREATECREATE_SUCCESSCREATE_FAIL动作。我的想法是在提交时发送CREATE。然后我有一个action-chain epic,它启动对服务器的service调用,并根据响应触发CREATE_SUCCESSCREATE_FAIL
问题
myaction-chain epic触发重复动作-在这两种情况下,它都会触发两个动作,例如:如果成功,对于每个CREATE它都会发送两个CREATE_SUCCESS动作。
代码

 private createAnimalActionChain() {
        return action$ => {
            return action$
                .ofType(AnimalActions.CREATE)
                .switchMap(action => {
                    return this.service
                        .create(action.payload)
                        .map(httpResponse => {
                            let response = httpResponse.json()
                            if (response.success) {
                                return this.actions.createSuccess()
                            }

                            return this.actions.createFail(response.errors)
                        })
                })
        }
    }

这就是我写的,而且大部分都在起作用。如果有更好的办法,我洗耳恭听。派遣多个行动直到最近才是真正的问题,但它似乎从来没有对我没问题,所以我很想解决它。
编辑:我刚刚发现,有时我的应用程序会在执行任何epic之前发送重复的操作。我现在想知道为什么。
编辑2:无需编辑。这是一个孤立的案例,submit事件一直冒泡到顶部,因为我将我的@Output()字段命名为“submit”-它导致了双重动作分派。现在已修复,与上述史诗问题无关。它仍然存在。
编辑3:在@jayphelps的帮助下,我能够跟踪这个问题。结果我的行动,从史诗的链条,触发了两次。但我不知道为什么会这样。这是我的旧密码:
static CREATE = 'CREATE'
static CREATE_SUCCESS = 'CREATE_SUCCESS'
static CREATE_FAIL = 'CREATE_FAIL'
@dispatch()
create = (animal: IAnimal) => ({
    type: AnimalActions.CREATE,
    payload: animal
})
@dispatch()
createSuccess = () => ({
    type: AnimalActions.CREATE_SUCCESS
})
@dispatch()
createFail = (errors: object) => ({
    type: AnimalActions.CREATE_FAIL,
    payload: errors
})

此代码发送CREATE一次,CREATE_SUCCESS两次和CREATE_FAIL两次。我删除了最后两个装饰:
static CREATE = 'CREATE'
static CREATE_SUCCESS = 'CREATE_SUCCESS'
static CREATE_FAIL = 'CREATE_FAIL'
@dispatch()
create = (animal: IAnimal) => ({
    type: AnimalActions.CREATE,
    payload: animal
})
createSuccess = () => ({
    type: AnimalActions.CREATE_SUCCESS
})
createFail = (errors: object) => ({
    type: AnimalActions.CREATE_FAIL,
    payload: errors
})

这个代码看起来工作正常,每个操作只触发一个。我很困惑为什么这样做。根据API docs这个属性修饰单个action creator函数并分派其返回值action对象。这很奇怪,因为我对@dispatch()CREATE的调用是相同的。这个装潢师是怎么工作的?
编辑4:
我已经将行为缩小到这个范围:如果我从我的史诗中调用一个动作,并且这个动作用CREATE_SUCCESS修饰,它将被触发两次。我怀疑epic作为一个中间件在内部发送接收到的操作。如果需要从容器组件手动分派操作,问题就来了。
解决方案
在Jayphelps的帮助下。谢谢你的回复。不过,我喜欢@dispatch装饰,用于我的组件内部。我发现的一个前个人解决方案是以一种方式构建我的动作链,这种方式@dispatch(从组件内部发送的)不会通过epic发送。然后用starter-actions装饰那些starter-actions就行了。

最佳答案

提供的代码很好;请看这里,只有一个CREATE_SUCCESShttps://jsbin.com/tagovok/edit?js,output
这表明问题出在这里没有提供的代码中。我能想到三种可能:
在某个地方,不知怎的,您正在分派两个CREATE操作(使用redux devtools查看)
this.service.create(action.payload)实际上会发射两个东西而不是一个(使用dodebuggers,或者你甚至可以在它之后添加一个.take(1),如果它修复了你知道的)
您已经添加了两次同一史诗,例如combineEpics(yourEpic, yourEpic)(这一次很难确认。可能尝试在epic it的初始调用中添加一个计数器,并确认它只被递增到1,因为epic函数本身只被调用过一次)
基于您的更新:
我已经将行为缩小到这个范围:如果我从我的史诗中调用一个操作,并且这个操作用@dispatch()修饰,那么它将被触发两次。我怀疑epic作为一个中间件在内部发送接收到的操作。如果需要从容器组件手动分派操作,问题就来了。
事实上,redux observate会自动分派epics发出的操作。我没有使用角红字的经验,但是这里有一些关于使用它的文档:https://github.com/angular-redux/store/blob/master/articles/epics.md
快速浏览一下就可以发现,他们并不使用史诗中的动作创造者,而只是使用pojo。您仍然可以创建只返回pojo操作的操作创建者,just normal redux

10-06 03:11