Created
July 7, 2016 13:30
-
-
Save owanturist/670f6580b5e400ba7f18298b92c76f8e to your computer and use it in GitHub Desktop.
Simple elm-app with normalized store
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Main exposing (main) | |
import Html.App | |
import Html exposing (Html, div, ul, li, form, input, button, strong, text) | |
import Html.Events exposing (onSubmit, onInput) | |
import Html.Attributes exposing (type', value) | |
import Dict exposing (Dict) | |
-- MODEL | |
type alias Todo = | |
{ id : Int | |
, title : String | |
} | |
type alias Model = | |
{ ids : Int | |
, nextTodo : String | |
, data : Dict String (Dict Int Todo) | |
, list : List Int | |
} | |
-- UPDATE | |
type Msg | |
= CreateTodo | |
| ChangeNextTodo String | |
update : Msg -> Model -> Model | |
update msg ({ ids, nextTodo, data, list } as model) = | |
case msg of | |
CreateTodo -> | |
let | |
newTodo = | |
Todo ids nextTodo | |
foo maybeTodos = | |
Just | |
<| case maybeTodos of | |
Just todos -> | |
Dict.insert ids newTodo todos | |
Nothing -> | |
Dict.fromList [ ( ids, newTodo ) ] | |
newData = | |
Dict.update "todos" foo data | |
in | |
{ model | |
| ids = ids + 1 | |
, nextTodo = "" | |
, data = newData | |
, list = list ++ [ ids ] | |
} | |
ChangeNextTodo newNextTodo -> | |
{ model | nextTodo = newNextTodo } | |
-- VIEW | |
buildTodosList : Model -> List Todo | |
buildTodosList { data, list } = | |
let | |
todosStore = | |
Maybe.withDefault Dict.empty (Dict.get "todos" data) | |
in | |
List.foldl | |
(\todoId acc -> | |
case (Dict.get todoId todosStore) of | |
Just todo -> | |
acc ++ [ todo ] | |
Nothing -> | |
acc | |
) | |
[] | |
list | |
view : Model -> Html Msg | |
view model = | |
div [] | |
[ form | |
[ onSubmit CreateTodo | |
] | |
[ input | |
[ type' "text" | |
, value model.nextTodo | |
, onInput ChangeNextTodo | |
] | |
[] | |
, button [ type' "submit" ] [ text "Add Todo" ] | |
] | |
, ul [] (List.map viewTodo (buildTodosList model)) | |
] | |
viewTodo : Todo -> Html Msg | |
viewTodo { id, title } = | |
li [] | |
[ strong [] [ text (toString id) ] | |
, text (" " ++ title) | |
] | |
-- MAIN | |
main : Program Never | |
main = | |
Html.App.beginnerProgram | |
{ model = Model 0 "" Dict.empty [] | |
, view = view | |
, update = update | |
} |
короч, не получится сделать так, как хотелось бы
type alias Todo =
{ id : Int
, title : String
}
type alias TodoList =
{ id : Int
, todos : List Int
}
data =
Dict.fromList
[ ( "todos"
, Dict.fromList
[ ( 1, Todo 1 "foo" )
, ( 2, Todo 2 "bar" )
, ( 3, Todo 3 "bar" )
, ( 4, Todo 4 "bar" )
]
)
, ( "todoLists"
, Dict.fromList
[ ( 1, TodoList 1 [ 1, 2, 3 ] )
, ( 2, TodoList 2 [ 3, 4 ] )
]
)
]
Не смотря на то, что data - словарь словарей, типы хранимые во вложенных словарях должны быть одинаковыми. Очень грустно
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
В общем, хочется, чтобы данные в сторе хранились в нормальной форме:
Есть ветвь в сторе, отвечающая за данные, судя по всему это
Dict String (Dict Int a)
, где строка - имя множества сущностей. На реальном проекте сущности это - пользователи, статьи, комментарии и т.д., в гисте - тудушкиDict Int Todo
и пока не знаю как туда же запихать списки туду (сейчас он один), хранящий лишь последовательность idTodo
.В дальнейшем, там где это необходимо, происходит денормализация данных, и они попадают во вьюху.
Затык происходит на строке - я не знаю как в типах описать тот факт, что у меня словари второго уровня, хранящие множества сущностей, могут содержать различные типы данных. Схематично, вот что бы я хотел увидеть