通过端口将事件处理程序从elm传递给JS

Pass event handler from elm to JS through port

在 JS 中我们有这样一个函数:

const handleClick = event => {
  event.preventDefault();
  // some more code
}

<button onClick={this.handleClick}>Add to bag</button>

我的 Elm 代码:​​

main.elm

port addToBag : Value -> Cmd msg

type Msg
  = ClickBag Item

update msg model =
  case msg of
   ClickBag item ->
      let
        data =
          Encode.object
            [ ("price", Encode.string item.price)
            , ("sku", Encode.string item.sku)
            ]
      in
        ( model, addToBag data )

view model =
  button [onClick ClickBag model.item] [text "Add to bag"]

index.html

<div id="elm"></div>

<script type="text/javascript">

  const addToBag = (params, btnSelector = null) => {
    console.log('json data', params)
  }

  const ElmApp = Elm.Main.init(document.getElementById('elm'))

  ElmApp.ports.addToBag.subscribe(addToBag)

</script>

目前,我可以获取 params 值,但不知道如何通过 [=15= 将事件处理程序(如 JS 代码中的 event)从 Elm 文件传递​​给 JS ](将该值传递给 btnSelector), 所以我可以将该值用于遗留代码。谁能帮帮我?

非常感谢!

您可以将完整的事件对象提取为 Value 并通过端口传递。

port toJS : Value -> Cmd msg

onClickWithValue : (Value -> msg) -> Attribute msg 
onClickWithValue toMsg =
    on "click" (Json.map toMsg Json.value)

update中有类似

的内容
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        SomeTag value ->
            ( { model | count = model.count + 1 }, toJS value )

附带说明一下,如果你传递给JS的值是基本值(Bool, Int, Float, String, Maybe, Json.Decode.Value 和List, Array, tuples or records of the previous types),您可以将它们作为记录传递。因此,在您的情况下,您可以:

type alias Item = 
    { price: String 
    , sku: String 
    }

port addToBag : (Item, Value) -> Cmd msg

type Msg
  = ClickBag Item Value

view model =
  button [onClickWithValue (ClickBag model.item)] [text "Add to bag"]

update msg model =
  case msg of
   ClickBag item value ->
        ( model, addToBag ( item, value ) )