在此example (RandomGifPair)中,与NewGif相对应的更新实际上是如何在父组件触发RandomGif.update act model.left
之后执行的?看来RandomGif.update NewGif maybeUrl
需要在某个地方手动触发。更明确一点,RandomGifPair会触发其Left更新动作,并通过手动调用RandomGif的update函数来获取模型/效果对。返回的效果通过Effects.map Left fx
执行,然后继续执行RandomGif中的getRandomGif函数。
getRandomGif : String -> Effects Action
getRandomGif topic =
Http.get decodeUrl (randomUrl topic)
|> Task.toMaybe
|> Task.map NewGif
|> Effects.task
据我所知,它将继续触发NewGif动作,由于Effects.map,该动作现在也标记为Left。我缺少的图片的唯一部分是如何将此动作保持在RandomGif的范围内,以及实际上触发了与此更新的NewGif情况相对应的动作:
update : Action -> Model -> (Model, Effects Action)
update action model =
case action of
RequestMore ->
(model, getRandomGif model.topic)
NewGif maybeUrl ->
( Model model.topic (Maybe.withDefault model.gifUrl maybeUrl)
, Effects.none
)
当Main.elm仅具有RandomGifPair的更新功能时,因此对于NewGif不适用。
我确定答案在于端口,Effects.map,forwardTo或我所缺少的任务的特定详细信息。
作为参考,here is an attempt to solve the problem in javascript在NewGif的上部更新函数中包含一个条目,并在其中手动调用RandomGif.update。可能不是尝试了解榆树的最佳方法。
最佳答案
所有操作都会进入您的顶级更新功能。无法将操作范围限定为子更新功能-它们始终位于顶部。因此,大多数程序将手动将操作路由到较低的更新功能。这就是这里发生的事情。所有动作都必须放入RandomGifPair.update
中,由该函数决定:a)调用子函数,以及b)将结果存储在状态中的正确位置。这可能令人惊讶地麻烦。
Here's the specific point in RandomGifPair.update
that does the routing。
第42行说:“哦,这是一个Left
动作?给我里面的act
。现在,您将所需的NewGif
或RequestMore
存储在act
中,并且您知道它已绑定第44行调用了下层更新函数,该函数知道如何处理。第46行将下层更新函数的结果存储在模型中(通过使用新的左边重新创建整个模型并重新使用旧的右边) 。
这些都被效果周围的样板遮盖了。如果您先了解动作的流程,然后再将相同的逻辑应用于“效果”,我想这将变得更加清楚。
关于javascript - 榆木效果映射到嵌套组件,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34947260/