我正在编写一个Elm应用程序,其中该州的主要部分位于Dict
,其中Record
为值。我有一个主状态模型的更新函数,以及Dict
中各个记录的更新函数。有没有办法将Dict.update
与记录状态更新功能一起使用?
我遇到的问题是记录的状态更新函数返回更新函数通常返回的内容:具有更新对象的元组和要触发的任何命令(例如(newRecord, Cmd.none)
)。但是Dict.update
函数需要记录并返回一条记录(例如只是newRecord
),而不是带有记录和命令对象的元组。
有解决方法吗?现在我已经使用Dict.get
和Dict.insert
的组合工作了,但这看起来很笨拙。
答案 0 :(得分:2)
如果记录的更新功能始终返回Cmd.none
,则可以简化它并仅返回更新的模型。
如果您的应用程序架构不需要,那么子模块不必遵循( Model, Cmd Msg )
约定。
如果您确实需要从较低级别传递命令,则还可以重新构建子模块的update
函数以简化这些更新。
以下是一个如何拆分更新的示例,以便您可以在顶级update
中重复使用相同的逻辑,而无需额外的诡计。
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
(updateModel msg model, updateCmd msg model)
updateCmd: Msg -> Model -> Cmd Msg
updateCmd msg model =
case msg of
MorePlease ->
getRandomGif model.topic
_ ->
Cmd.none
updateModel: Msg -> Model -> Model
updateModel msg model =
case msg of
NewGif (Ok newUrl) ->
Model model.topic newUrl
_ ->
model
如果您需要updateCmd
中的更新模型,那么只需传递它而不是当前模型,或者如果您愿意,也可以传递它们。
作为奖励,您可以完全省略案例表达的未使用分支。
Dict.update
也可以在updateModel
中使用Dict.update
而无需检索记录并将其写回。
Dict.update childKey (Maybe.map (updateModel childMsg)) model
答案 1 :(得分:1)
不是我知道的。我在我的一个项目中有这个辅助函数
updateDict : comparable -> msg -> Dict comparable b -> (msg -> b -> ( b, Cmd msg )) -> (comparable -> msg -> c) -> ( Dict comparable b, Cmd c )
updateDict uid act dict fn wrapper =
case Dict.get uid dict |> Maybe.map (fn act) of
Just ( m, e ) ->
( Dict.insert uid m dict
, Cmd.map (wrapper uid) e
)
Nothing ->
( dict, Cmd.none )
答案 2 :(得分:1)
不确定这是否是您要找的,但如果您的模型中有嵌套的Dict
结构,请执行以下操作:
type alias Model =
{ parentsAndChildren : Dict String (Dict String Int) }
然后没有必要让孩子update
输出Cmd
。您的更新可能如下所示:
update : Msg -> Model -> Model
update msg model =
case msg of
NewChild parentName childName age ->
let
newModel =
{ model
| parentsAndChildren =
model.parentsAndChildren
|> Dict.update
parentName
(Maybe.map insertChild)
}
in
(newModel, Cmd.none)
-- helper function to update a child Dict
insertChild: String -> Int -> Dict (String Int) -> Dict (String Int)
insertChild name age childDict =
Dict.insert name age childDict
NEEDS 输出update
的唯一Cmd
功能是顶级组件中的更新功能。
因此,您的孩子update
功能无需输出Cmd
。