iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 9
0
Modern Web

學會Elm寫前端系列 第 9

09 elm 和javascript如果合作?

interop with javascript

所以elm可以呼叫javascript的function嗎?或是javascript可以使用elm的function?
答案是不行的,他們兩個之間能做的就是傳遞data,就像上一篇和server
之間的溝通一樣,data in , data out Elm 會稱之為 Javascript as a
service
。但是和server 之間溝通還是有不一樣的地方。

use port

也就是說,在 elm 端要有一個port, js 端也要一個port; elm傳給js,js 也要傳給elm, elm
可以用decoder,decode js的 object。 以下的例子來自於 elm port example

port check : String -> Cmd msg

---- UPDATE ----
type Msg
    = Change String
    | Check
    | Suggest (List String)


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Change newWord ->
            ( Model newWord [], Cmd.none )

        Check ->
            ( model, check model.word )

        Suggest newSuggestion ->
            ( Model model.word newSuggestion, Cmd.none )


-- view
view : Model -> Html Msg
view model =
    div []
        [ div [] [ text "Input number of sentences desired" ]
        , div [] [ text "The Donald markov sentence generator" ]
        , input [ onInput Change ] []
        , button [ onClick Check ] [ text "Generate" ]
        , div [] [ text (String.join " " model.suggestions) ]
        ]

這是是elm 端要把東西丟給js的,當下按下按鈕,會透過 Msg 到elm runtime 給 update, 會發動 check model.word 再透過 Cmd msgelm runtimemodel.word 變成 可以給 elm
runtime 的 msgmsgMsg 不一樣的是,一個是我們定義給 update 判讀的 Msg
,一個是任意的 msg type。之前我們也有提過,你也可以叫 a type。

app.ports.check.subscribe(function(num) {
  let suggestions = Number.isInteger(parseInt(num))
    ? generateChat(num)
    : "Unable to Parse " + num;
  // invoke JS function, return array of strings
  app.ports.suggestions.send(suggestions.split(" ")); // sending to the Elm sub
});

subscription

簡單的來說,subscriptions就是從外在的世界,送 Msgupdate ,本來應該是 Elm runtime 會送出Msg 出來給 update 的function。

app.ports.suggestions.send(suggestions.split(" ")); // sending to the Elm sub
---- Subscription ---
-- port for listening for suggestions from JavaScript

port suggestions : (List String -> msg) -> Sub msg


subscriptions : Model -> Sub Msg
subscriptions model =
    suggestions Suggest

...

type Msg
    = Change String
    | Check
    | Suggest (List String)

...

Suggest newSuggestion ->
            ( Model model.word newSuggestion, Cmd.none )

參考資料

  • elm town episode 13 :這一期是講
    history of port,是Elm發明人Evan自己出來講的,講一些他發展的過程還有他的思考流程。
  • ports by example :
    這是javascript to elm 裡的一期,把相關 port 的資料都整理的相當不錯。如果有興趣可以看看actor
    model,有一兩個youtube的教學,這也是port的理論基礎。實用。
  • 官方版的說明 :
    也是值得一看。和javascript可以互相溝通有很多效果,可以讓你的code不用重新發明輪子,可以和本來就有的js庫使用,或是易於和其他api串接(譬如stripe只有提到js的api),或是本來程式的一小部分想要先使用elm。

上一篇
08 如何讓Elm和server說上話?
下一篇
10 如何在elm寫測試?(test in elm)
系列文
學會Elm寫前端30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言