スポンサーリンク

Elm0.19でlocalStorage利用のTODOアプリ(1)フラグflags

2019年5月6日

ElmでTodoアプリを作成したい!

まずは、TODOリストの保存先として、LogalStorageを利用したい。LocalStorageでは、個々のWEBブラウザに、5MBまでデータを保存でき、ユーザーが一度ブラウザを閉じても、再度そのサイトに行けば、TODOアプリのリストを呼び出すことができます。

WebStorage API(LocalStorage)の詳細については以下が参考になります。
https://qiita.com/masamitsu-konya/items/c69515604570150d3ab9

@masamitsu-konya
2017年08月28日に更新
WebStorage API(LocalStorage)を使ってみた

https://www.granfairs.com/blog/staff/local-storage-01

ブラウザにデータを保存するlocalStorage(ローカルストレージ)の使い方
Posted by NAGAYA on Oct 26th, 2017

Elm0.19は2019年5月現在、localStorageをサポートしていないので、Elmのportというものを用いて、Elmの外側で、Javascriptを記載して、localStorageを利用しないといけません。

以下の本のP172-P178を参考にしつつ、tryしてみたいと思います。

初回の今回は、https://superhahnah.com/elm-flags/ を写経して、『flags』を介して、アプリ開始時に、index.html(JavaScript)からデータをsrc/Main.elm(Elm)に送ってみたいと思います。

スポンサードリンク

Elm0.19でlocalStorage利用のTODOアプリ目次

開発環境

Windows 10 Pro
Chrome
VisualStudioCode 1.32.3
git version 2.20.1.windows.1
nvm 1.1.7
node 10.2.0
npm 6.4.1
elm 0.19.0-bugfix6
elm-format 0.8.1
VisualStudioCodeの拡張機能でelmをインストールして、settings.jsonに以下のようにelmを設定。
(『Alt + Shift + F』と『Ctrl + S』を使用。)

    "[elm]": {
        "editor.formatOnSave": true
    },

ElmのPortについて

ポートPortを使うと、Elmの実行中にJavaScriptとデータをやり取りすることができます。今回は、TODOをCreate, Read, Update, Deleteするときに、ElmアプリからlocalStorageにそれぞれの動作ができるようにしたいと思います。

そのためには、まずは以下を読んで理解する必要があります。

https://guide.elm-lang.jp/interop/
JavaScriptとの相互運用

ElmからJavaScriptにデータを送信するとき

Elm側

port module Main exposing (..)

port 関数名 : 送信するデータの型 -> Cmd msg

JavaScriptから送信されたデータをElmで受信するとき

Elm側

port 関数名 : (受信するデータの型 -> msg) -> Sub msg

index.html側(JavaScript側)については、またあとで、、、

src/Main.elmをmain.jsにコンパイルしてindex.htmlから読み込む

https://guide.elm-lang.jp/interop/   を参考にしつつ、以下のサイトを写経してみたいと思います。

https://superhahnah.com/elm-flags/

「index.htmlのJavaScript から 、src/Main.elmのElm へ数値(今回は4)を渡し、Elm がその数値の回数分だけHello World!と表示する」アプリをの実装を行います。

ポイントは以下の3つのようです。

  • src/Main.elmから elm make src/Main.elm --output=main.jsにより、main.jsを作成し、index.html(JavaScript)から読み込む
  • Main.elmがindex.htmlのJavaScriptからデータを受け取れるように、Main.elmのmain関数はBrowser.elementを用いる
  • index.htmlの<body></body>内に以下のようなコードを記載することにより、Elmを初期化する(flagを介して、JavaScriptから
    Elmにデータを送る)
<!DOCTYPE HTML>
<html>
<head>
  <meta charset="UTF-8">
  <title>Main</title>
  <script src="main.js"></script>
</head>

<body>
  <div id="elm"></div>
  <script>
  var app = Elm.Main.init({
    node: document.getElementById('elm'),
    flags: 4
  });
  </script>
</body>
</html>

( 引用元:https://superhahnah.com/elm-flags/

C:/elm/ フォルダ内に elm-flag/ フォルダを作成し、フォルダをVisualStudioCodeで開き、Ctrl+@ でコマンドプロンプトを開き、以下を入力。(何か聞かれたらEnterを押す)

すると、src/ フォルダとelm.jsonが作成されます。

elm init

index.htmlの作成

index.htmlを新規作成し、 
https://guide.elm-lang.jp/interop/  にある、index.htmlをコピペします。

また、cssフレームワークbulmaを読み込んでおきます。

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css">
<script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>

ここでflagsを経由してJavaScriptからElmへデータを伝えるために、var app = Elm.main.init({});の中に、 flags: 4の などのように記載します。

<script>
  var app = Elm.Main.init({
    node: document.getElementById('elm'),
    flags: 4
  });
</script>

flags: 4 のところは、他にも、以下のような記載方法があるようです。

flags: 4
flags: "Hello!"
flags: Date.now()
flags: {greeting: "Hello Again, World!", times: 8}

src/Main.elmの作成(Browser.elementテンプレート)

src/ フォルダに、src/Main.elm ファイルを作成します。

Elmでフラグを扱うには、JavaScriptから渡された値を、Elm側で受け取る必要があります。 Browser.element関数を使うと、initでフラグを受け取ることができるようになるそうです。

参考:https://qiita.com/jinjor/items/245959d2da710eda18fa

@jinjor
2018年12月03日に更新
Elm Advent Calendar 20182日目
Elm 0.19 の初期化方法 6 種類

https://qiita.com/miyamo_madoka/items/aa499d2f0fa756065a06

@miyamo_madoka
2018年12月16日に更新
Elm2(完全版) Advent Calendar 201816日目
ElmのBrowser.*の使い分け

Browser.element関数 のテンプレート
(間違っている可能性大です。今後訂正必要ある可能性が高いです。)

MODELの作成

MODEL, UPDATE, VIEWの順に作成していきます。

Elmアプリがもつ状態として、index.html(JavaScript)から受け取る数値を”times”を定義します。

また、index.html(JavaScript)から、flagsを介して 4 という数字を受け取り、初期化の時点でtimesに代入します。ここが今回のキモでしょうか。。。

-- MODEL

type alias Model = { times : Int }

init : Int -> ( Model, Cmd msg )
init flags =
  ( { times = flags }, Cmd.none )

UPDATEの作成

今回は、特にUPDATEは必要ないので、以下のようなコードになります。

type Msg
  = NoMessage

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

VIEWの作成

CSSフレームワークbulmaで手間取りましたが、今回のポイントは以下のコードです。

ul [ class "list is-hoverable" ]
  (List.repeat model.times
    (li [ class "list-item" ] [ text "Hello World!" ])
  )

画像ファイルlogo.svgを用意

https://github.com/halfzebra/create-elm-app/blob/master/template/public/logo.svg から、logo.svgをダウンロードして、index.htmlと同じ階層に保存します。

src/Main.elm のVIEWでは、img [ src ".logo.svg" ] [] のように記載すると、画像を表示することができます。

bulmaで見栄えを整えると、以下のような感じでしょうか。

section [ class "section" ]
            [ div [ class "container" ]
                [ section []
                    [ figure [ class "image container is-128x128" ]
                        [ img [ src "./logo.svg" ] []
                        ]
                    ]
                ]
            ]

src/Main.elmをmain.jsにコンパイル

VisualStudioCodeのターミナル画面(Ctrl+@)で以下を入力して、src/Main.elmをmain.jsにコンパイルします。

elm make src/Main.elm --output=main.js

そして、index.htmlをChromeで開くと、以下のようになります。

GitHubにアップロード

GitHub上で、elm-bulma-flag という名前のリポジトリを作成し、指示に従ってpushします。

echo "# elm-bulma-flag" >> README.md
git init
git add README.md
git commit -m "first commit"
git remote add origin https://github.com/adash333/elm-bulma-flag.git
git push -u origin master

Settingsをクリックして、下の方へ行き、GitHub PagesのSourceを”None”から”master branch”に変更。その後、画面が変わるので、公開アドレスのリンクをクリック。

ソースコードとDEMOサイト

ソースコード: https://github.com/adash333/elm-bulma-flag

DEMOサイト: https://adash333.github.io/elm-bulma-flag/

参考サイト

https://github.com/evancz/elm-architecture-tutorial
An Introduction to Elm内にあるソースコードが記載されています。

https://github.com/evancz/elm-todomvc
LocalStorageを用いたTODOアプリのソースコードです。

https://qiita.com/sand/items/3767d263f98b3dad264e
@sand
2018年05月12日に更新
複数のElmアプリで小さなデータを共有する – Local storage

https://superhahnah.com/elm-flags/
[Elm] Flags: JavaScript から Elm を引数付きで初期化する
投稿者: hahnah 投稿日: 2018-12-04

スポンサーリンク