所以elm可以呼叫javascript的function嗎?或是javascript可以使用elm的function?
答案是不行的,他們兩個之間能做的就是傳遞data,就像上一篇和server
之間的溝通一樣,data in , data out Elm 會稱之為 Javascript as a
service 。但是和server 之間溝通還是有不一樣的地方。
也就是說,在 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 msg
經 elm runtime
把 model.word
變成 可以給 elm
runtime 的 msg
。 msg
和 Msg
不一樣的是,一個是我們定義給 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
});
簡單的來說,subscriptions就是從外在的世界,送 Msg
給 update
,本來應該是 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 )
port
的資料都整理的相當不錯。如果有興趣可以看看actor