简体   繁体   中英

Handling custom events in Fable-Elmish

Hot on the heels of my previous question the example I am working on in "Elm in Action" (and trying to port to Fable-Elmish) has a custom event from a custom element. In the html file I have the following:

<link rel="stylesheet" href="http://elm-in-action.com/range-slider.css">
<script src="http://elm-in-action.com/range-slider.js"></script>
<script>
  class RangeSlider extends HTMLElement {
    connectedCallback() {
      var input = document.createElement("input");
      this.appendChild(input);

      var jsr = new JSR(input, {
        max: this.max,
        values: [this.val],
        sliders: 1,
        grid: false
      });

      var rangeSliderNode = this;

      jsr.addEventListener("update", function(elem, value) {
        var event = new CustomEvent("slide", {
          detail: {userSlidTo: value}
        });

        rangeSliderNode.dispatchEvent(event);
      });
    }
  }

  window.customElements.define("range-slider", RangeSlider);
</script>

In the example in the book (in Elm, of course) the first step in receiving the events is to do something like the following:

onSlide : (Int -> msg) -> Attribute msg
onSlide toMsg =
  let
    detailUserSlidTo : Decoder Int
    detailUserSlidTo =
        at [ "detail", "userSlidTo" ] int

    msgDecoder : Decoder msg
    msgDecoder =
        Json.Decode.map toMsg detailUserSlidTo
in
    on "slide" msgDecoder

which can be simplified to:

onSlide : (Int -> msg) -> Attribute msg
onSlide toMsg =
  at [ "detail", "userSlidTo" ] int
    |> Json.Decode.map toMsg
    |> on "slide"

In Elmish, however, there is no equivalent that I can find to on . I have come up with:

let onSlide (toMsg: int -> Msg) =
  Decode.at ["detail", userSlidTo"] Decode.int
  |> Decode.map toMsg
  |> ... // Now what!?

I have looked through the sources in everything I can think of that might apply but can't find a way to listen to custom events. And, again, the documentation doesn't provide any examples or explanations of how to do this that I have found.

There has to be a way to connect to custom events in Elmish, but I just can't find it anywhere. Is the approach to doing the same thing is different in the two environments?

So, to answer my own question, it appears that Elmish doesn't work the same way that Elm does in this case. The mechanism would appear to be to set up a subscription in Elmish something along the lines of:

let sliderSub  (initial: model) =
    let sub dispatch =
        window.addEventListener ("slide, fun evt ->
            let detail = <decode event details>
            match detail with
            | Ok slidEvt -> <dispatch a Cmd based on the details>
            | _ -> ()
        )
    Cmd.ofSub sub

Program.mkProgram init update view
|> Program.withSubscription sliderSub
...

I haven't gotten this to work yet as there are other issues still to be dealt with but this appears to be the approach needed in Elmish.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM