Передать результаты querySelectorAll в EventTarget.addEventListener

Я хочу сделать что-то вроде:

open Webapi.Dom;

let addListener = (element) =>
    EventTarget.addEventListener("click", onSubscribeClick, EventTarget.asEventTarget(element));

let addOrRemoveListeners = (handler, ()) => {
    let elements = Document.querySelectorAll({j|[$subscriptionIdAttr]|j}, document);
    Js.Array.forEach(handler, NodeListRe.toArray(elements) |> Js.Array.map(Element.ofNode))
  };

let addListeners = addOrRemoveListeners(addListener);

let removeListeners = addOrRemoveListeners(removeListener);

Но я получаю ошибку в addOrRemoveListeners(addListener);:

This is:
  (Dom.eventTarget) => unit
But somewhere wanted:
  (Dom.node) => unit

Как мне конвертировать из Dom.eventTarget в Dom.node?


Изменить: я закончил с этим:

let addListener = Element.addEventListener("click", onSubscribeClick);
let removeListener = Element.removeEventListener("click", onSubscribeClick);
let addOrRemoveListeners = (handler, ()) => {
  let elements = Document.querySelectorAll({j|[$(subscriptionIdAttr)]|j}, document);
  let () =
    elements
    |> NodeListRe.toArray
    |> Array.map(Element.ofNode)
    |> Array.to_list
    |> List.filter(Js.Option.isSome)
    |> List.map(Js.Option.getExn)
    |> List.iter(handler);
  ()
};
let addListeners = addOrRemoveListeners(addListener);
let removeListeners = addOrRemoveListeners(removeListener);

1 ответ

Решение

Короткий ответ:

external eventTargetToNode : Dom.eventTarget => Dom.node = "%identity";

eventTarget может быть почти чем угодно, и, к сожалению, нет хорошего способа выяснить, что это такое. В JavaScript это просто выводится пользователем в зависимости от контекста (возможно, этот контекст можно перенести в параметр типа, но это где-то в будущем).

Так что на данный момент вам придется сделать небезопасный бросок, чтобы получить то, что вам нужно.

(Кстати, вы можете использовать Element.addEventListener чтобы избежать броска из element в eventTarget)

Другие вопросы по тегам