在Fable Elmish中处理自定义事件



继我之前的问题之后,我正在处理的示例;Elm in Action";(并试图移植到FableElmish(具有来自自定义元素的自定义事件。在html文件中,我有以下内容:

<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>

在书中的例子中(当然是在Elm中(,接收事件的第一步是执行以下操作:

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

可以简化为:

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

然而,在Elmish中,我找不到on的等价物。我想出了:

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

我已经查阅了我能想到的可能适用的所有来源,但找不到倾听自定义事件的方法。同样,文档中没有提供我发现的任何关于如何做到这一点的示例或解释。

必须有一种方法来连接Elmish中的自定义事件,但我在任何地方都找不到。在这两种环境中,做同样事情的方法是否不同?

因此,为了回答我自己的问题,Elmish的工作方式似乎与Elm在这种情况下的工作方式不同。该机制似乎是在Elmish中建立订阅,大致如下:

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
...

我还没有做到这一点,因为还有其他问题需要处理,但这似乎是Elmish所需要的方法。