在 Elm 中从 parent 更改小部件模型

Change widget model from parent in Elm

我在 Elm 中使用 "compose" pattern

Main.elm 中,我正在使用以下内容为 Random 生成初始种子:

type alias Model =
    { ...
    , seed : Seed
    }

initialModel : Model
initialModel =
    { ...
    , seed = initialSeed 0
    }

init : ( Model, Cmd Msg )
init =
    ( initialModel, generate InitializeSeed (int minInt maxInt) )

type Msg
    = ...
    | InitializeSeed Int

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        ...

        InitializeSeed value ->
            ( { model | seed = Random.initialSeed value }, Cmd.none )

这似乎很适合将随机数生成器种子初始化为随机起始值。

我有一个在主应用程序中使用的 "independent" 小部件。我想在收到 InitializeSeed 消息后将种子传递给那个小部件,然后在 child 小部件(使用 Random.step)中更改时检索值,这样我就可以在需要生成器时更新其他小部件的种子。

如何从 Main 中的 update 函数为 child 小部件生成消息,以便我可以将种子传递给 child? child return 更新后的种子如何返回到 parent?

更新:

我想出了如何将种子传递给 child 小部件,尽管我不确定这是最好的方法。

child 代码如下所示:

type alias Model =
    { ...
    , seed : Seed
    }

replaceSeed : Model -> Seed -> Model
replaceSeed model seed =
    { model | seed = seed }

并且在 parent 中,我修改了 update 函数,如下所示:

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        ...
        InitializeSeed value ->
            let
                seed =
                    Random.initialSeed value

                child_ =
                    Child.replaceSeed model.child seed
            in
                ( { model
                    | seed = seed
                    , child = child_
                  }
                , Cmd.none
                )

我仍在寻找获得 child return 更新种子的方法。

虽然任何 Elm 程序中的顶级更新函数 必须

update : Msg -> Model -> (Model, Cmd Msg)

对其后代的形状没有任何限制。所以没有什么能阻止你定义你的 child

update : Seed -> Msg -> Model -> (Model, Cmd Msg, Seed)

或者,如果 child 从不 returns 任何命令

update : Seed -> Msg -> Model -> (Model, Seed)

也许您有几件事要传递,例如 parent 消息。那么你可以走到

type alias Config msg = 
    { seed : Seed 
    , someParentMessage : String -> msg 
    }

update : Config msg -> Msg -> Model -> (Model, Maybe (Cmd msg), Seed)

当然,您需要在 Main 中适当地连接所有这些,但编译器会提供帮助。