Skip to content

Instantly share code, notes, and snippets.

@bcardiff
Created October 1, 2016 22:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bcardiff/d59fa6b70d4aa486534b485049c5be8e to your computer and use it in GitHub Desktop.
Save bcardiff/d59fa6b70d4aa486534b485049c5be8e to your computer and use it in GitHub Desktop.
Elm Html.App.map vs virtual dom reuse
{
"version": "1.0.0",
"summary": "helpful summary of your project, less than 80 characters",
"repository": "https://github.com/user/project.git",
"license": "BSD3",
"source-directories": [
"."
],
"exposed-modules": [],
"dependencies": {
"elm-lang/core": "4.0.5 <= v < 5.0.0",
"elm-lang/html": "1.1.0 <= v < 2.0.0"
},
"elm-version": "0.17.1 <= v < 0.18.0"
}
port module Main exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Html.App
type Model
= NotWrapped
| OtherNotWrapped
| Wrapped
type Msg
= ChangeDom
| ChangeModel Model
| WrappedMsg Msg
port changeDom : String -> Cmd msg
main =
Html.App.program
{ init = ( NotWrapped, Cmd.none )
, view = view
, update = update
, subscriptions = always Sub.none
}
update msg model =
case msg of
ChangeDom ->
( model, changeDom "my-div" )
ChangeModel nextModel ->
( nextModel, Cmd.none )
WrappedMsg innerMsg ->
case innerMsg of
ChangeDom ->
( model, changeDom "my-div" )
ChangeModel nextModel ->
( nextModel, Cmd.none )
WrappedMsg innerMsg ->
Debug.crash "will never happen"
view model =
case model of
Wrapped ->
Html.App.map WrappedMsg (reusableView model)
_ ->
reusableView model
reusableView model =
div []
[ button [ onClick ChangeDom ] [ text "append child from js in #my-div" ]
, button [ onClick (ChangeModel OtherNotWrapped) ] [ text "set model OtherNotWrapped, render without App.map" ]
, button [ onClick (ChangeModel Wrapped) ] [ text "set model Wrapped, render using App.map" ]
, div [] [ text <| "model: " ++ (toString model) ]
, div [ id "my-div" ] []
]
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript" src="/_compile/Main.elm"></script>
<script type="text/javascript">
var app = Elm.Main.fullscreen();
var i = 0;
app.ports.changeDom.subscribe(function(id) {
i++;
var child = document.createElement('div');
child.innerHTML = "" + i;
document.getElementById(id).appendChild(child);
});
</script>
</body>
</html>
@bcardiff
Copy link
Author

bcardiff commented Oct 1, 2016

Alternative view / reusableView that works

view model =
    case model of
        Wrapped ->
            reusableView WrappedMsg model

        _ ->
            reusableView identity model


reusableView wrapMsg model =
    div []
        [ button [ onClick (wrapMsg <| ChangeDom) ] [ text "append child from js in #my-div" ]
        , button [ onClick (wrapMsg <| ChangeModel OtherNotWrapped) ] [ text "set model OtherNotWrapped, render without App.map" ]
        , button [ onClick (wrapMsg <| ChangeModel Wrapped) ] [ text "set model Wrapped, render using App.map" ]
        , div [] [ text <| "model: " ++ (toString model) ]
        , div [ id "my-div" ] []
        ]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment