How to do Context in 0.17 (passing in multiple Addesses to a view)

111 views
Skip to first unread message

Sean Clark Hess

unread,
Jul 27, 2016, 6:38:59 PM7/27/16
to Elm Discuss
For the app I'm working on, I would like to create some views that have no update function or message. In 0.16, you could pass in extra addresses to a view. The example in the elm architecture lumped them together in a Context parameter.

I found this useful in 0.16 when creating very general views that didn't manage their own state. This approach was analogous to when you pass in a callback as a prop in React, if that helps.

How does one do this in 0.17?

Specifically I'm thinking about the use case of a general view function that takes any HTML children, but has some events that need to fire (like an accordion container opening and closing).

Noah Hall

unread,
Jul 27, 2016, 7:37:29 PM7/27/16
to elm-d...@googlegroups.com
This is what our accordion looks like in 0.17:

https://gist.github.com/eeue56/d0a2f901dc2fe36ab4562940b7fd28e4

it was a +7 -11 diff :)


Otherwise, you want `Html.App.map`. Make a component that has it's own
"update" function, with it's own messages. Map them and pass the
messages down from the top level in a wrapper to the `update` function
for that component. E.g


type MessageLevel = TopLevel Msg | SomeGenericViewLevel SomeGenericView.Msg
> --
> You received this message because you are subscribed to the Google Groups
> "Elm Discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elm-discuss...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Peter Damoc

unread,
Jul 28, 2016, 1:53:00 AM7/28/16
to Elm Discuss
I like the Context record pattern. It's simple and can be extended.
You can start with a context record and, if the view gets more general purpose you can slowly move to a signature similar to those found in Html components where you would make its fields optional.

type alias Context msg =
    { someValue : String
    , onMsg1 : Maybe msg
    , onMsg2 : Maybe msg
    }


defaultContext =
    { someValue = ""
    , onMsg1 = Nothing
    , onMsg2 = Nothing
    }


type alias Attribute msg =
    Context msg -> Context msg


someValue : String -> Attribute msg
someValue value ctx =
    { ctx | someValue = value }


onMsg1 : msg -> Attribute msg
onMsg1 msg ctx =
    { ctx | onMsg1 = msg }


onMsg2 : msg -> Attribute msg
onMsg2 msg ctx =
    { ctx | onMsg2 = msg }




view : List (Attribute msg) -> List (Html msg) -> Html msg
view props children =
    let
        ctx =
            List.foldl (\p acc -> p acc) defaultContext props

        content =
            div [] [text ctx.someValue]
    in
        div []
            [ content
            , div [] children
            ]






--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
There is NO FATE, we are the creators.
blog: http://damoc.ro/
Reply all
Reply to author
Forward
0 new messages