Elm 模态对话框

Elm modal dialog box

如何将 this 甜蜜的对话框集成到我的 Elm 代码中。我在 index.html 中包含了 JS 和 CSS。如何在我的更新函数中调用此 JavaScript 函数?

update : Action -> Model -> (Model, Effects Action)
update action model =
  case action of
    Submit ->
      let valid = length model.name > 0
      in
        if valid 
          then (model, swal({"title": "Invalid name"}))
          else (model, swal({"title": "Valid name"}))

在没有要检查的所有视图代码的情况下组装一个完整的示例是很棘手的,但我希望这个更简单的版本能有所帮助!从 this repo...

延伸到某些部分

index.html

<!DOCTYPE html>
<html>
  <head>
    <script src="Main.js" type="text/javascript"></script>
        <script type="text/javascript"
            src="bower_components/sweetalert/dist/sweetalert.min.js"
        ></script>
        <link rel="stylesheet"
            href="bower_components/sweetalert/dist/sweetalert.css"
        />
  </head>
  <body>
        <div id="main"></div>   
        <script type="text/javascript">

            var so = Elm.embed(Elm.Main, document.getElementById('main'));
            so.ports.callSwal.subscribe(doAlert); 
            function doAlert(space) {
                    if (space) swal("Hey, a spacebar!");
            }

        </script>
  </body>
</html>

modal.elm

import Graphics.Element
import Keyboard


port callSwal : Signal Bool
port callSwal =
    Keyboard.space


main = Graphics.Element.show "How about pressing a spacebar?"

我为让它工作所做的事情

$ bower install sweetalert
$ elm-make modal.elm --output=Main.js

备注

  • 嵌入Elm应用,给js一个对象访问(此处为“so”)
  • 在js中,订阅一个命名端口,并给它一个回调函数。
  • 在 elm 中创建端口。这个需要一个简单的 Bool,但我想你的至少需要一个 String

更好的答案

原来是注意到 startApp 内置了一个邮箱,您可以通过 app.model.

访问该邮箱

警报消息成为您模型的一部分。如果它是一个空字符串,我们将其解释为 "don't trigger any alerts".

NB. 我不知道为什么 update 需要 return 一个包含 Events Action 的元组。这里没有用到..

这里有一个例子:

var so = Elm.embed(Elm.Main, document.getElementById('main'));
so.ports.alert.subscribe(function(text) {
    if (text.length > 0) swal(text);
});
import StartApp
import Task exposing (Task)
import Effects exposing (Effects, Never)
import Html exposing (Html, div, input, button, text)
import Html.Events exposing (on, onClick, targetValue)
import String exposing (length)


app :
  { html : Signal Html
  , model : Signal Model
  , tasks : Signal (Task Never ())
  }
app =
  StartApp.start
    { init = init
    , update = update
    , view = view
    , inputs = []
    }


port alert : Signal String
port alert =
    Signal.map (\n -> n.alert) app.model


main : Signal Html
main =
  app.html


-- MODEL

type alias Model =
  { name : String
  , alert : String
  }


init : (Model, Effects Action)
init =
  ( { name = ""
    , alert = ""
    }
  , Effects.none
  )


-- UPDATE

type Action
    = Submit
    | TextEntry String


update : Action -> Model -> (Model, Effects Action)
update action model =
  case action of

    Submit ->
      if length model.name > 0 then
        ({ model | alert = "Valid name" }, Effects.none)
      else
        ({ model | alert = "Invalid name" }, Effects.none)

    TextEntry txt ->
      ({ model | name = txt, alert = "" }, Effects.none)


-- VIEW

view : Signal.Address Action -> Model -> Html
view address model =
  let f = (\str -> Signal.message address (TextEntry str)) in
  div
    []
    [ input
      [ on "input" targetValue f ]
      []
    , button
      [ onClick address Submit ]
      [ text "Submit" ]
    ]