【发布时间】:2021-02-19 21:03:30
【问题描述】:
问题总结 我在 elm 0.19.1 中使用 webcomponents。 目标是当 webcomponent 属性“requeststate”改变时,webcomponent 发出一个事件。 事件已发出(我可以在 webcomponent 构造函数的日志中看到),但 elm 没有正确触发“WebcomponentEvent”。 问题出现在 Windows 10 和 ubuntu 16.04、firefox 和 chrome 上。 未测试旧版 elm。
重现步骤:
- 我在这个最小的 repo 中重现了这个问题: https://github.com/Derryrover/elm_webcom_bug
- 使用以下命令编译 elm: elm make src/Main.elm --output elm.js --debug
- 使用网络服务器(例如“服务”)在本地托管
- 单击“请求”按钮。这将更改 web 组件上的属性“requeststate”。这反过来会触发 web 组件上的自定义事件“创建”。但是 elm 没有收到这个事件..
打开 elm 调试器或再次单击“请求”按钮将神奇地使事件在 elm 中触发。奇怪的。 我也做了分支'tom-experiment'。在这个分支中,我从 webcomponent-click 工作中得到了事件,但前提是我直接点击了 webcomponent 本身。
这个问题的重要性 为什么我想通过更改属性来触发 Web 组件上的事件? 这种方法的目标也是 JavaScript 互操作。 例如,我现在可以使用这个 web 组件来创建日期时间或 uuid 或做一些其他的 javascript 魔术。这样我就可以完全解决端口问题。 这个问题的解决方案可能会解决整个 Javascript 互操作讨论!
代码
这是我的 Main.elm:
module Main exposing (..)
import Browser
import Html
import Html.Attributes
import Html.Events
import Json.Decode
main =
Browser.sandbox
{ init = init
, view = view
, update = update
}
type alias Model =
{ request : Bool
, received: Bool
}
init : Model
init = { request = False
, received = False
}
type Msg
= Request
| Reset
| WebcomponentEvent
update : Msg -> Model -> Model
update msg model =
case msg of
WebcomponentEvent ->
{ model | received = True}
Request ->
{ model | request = True }
Reset ->
{ model | request = False , received = False}
view : Model -> Html.Html Msg
view model =
Html.div []
[ Html.button [Html.Events.onClick Request] [Html.text "Request"]
, Html.div
[]
[ Html.text "requested:"
, Html.text (if model.request then "true" else "false")
]
, Html.div
[]
[ Html.text "received:"
, Html.text (if model.received then "true" else "false")
]
, Html.button [Html.Events.onClick Reset] [Html.text "Reset"]
, Html.node "webcomponent-test"
[ Html.Events.on "created" (Json.Decode.succeed WebcomponentEvent)
, Html.Attributes.attribute "requeststate" (if model.request == True then "requested" else "idle")
] []
]
这是 webcomponent.js
class Webcomponent extends HTMLElement {
static get observedAttributes() {
return [
"requeststate"
];
}
attributeChangedCallback(name, oldValue, newValue) {
switch (name) {
case "requeststate":
if (newValue === "requested") {
console.log(`requested in webcomponent triggered`);
const customEvent = new CustomEvent('created', {detail: ""});
this.dispatchEvent(customEvent);
}
}
}
constructor() {
super();
this.addEventListener('created', function (e) {
console.log("event triggered as sensed by javascript: ", e.detail, e);
}, false, true);
}
}
customElements.define('webcomponent-test', Webcomponent);
这是我的 index.html
<!doctype html>
<html>
<head>
<script type="module" src="./webcomponent.js"></script>
<script src="./elm.js"></script>
</head>
<body>
<div id="elm_element"></div>
<script>
var app = Elm.Main.init({
node: document.getElementById('elm_element')
});
</script>
</body>
</html>
【问题讨论】:
标签: web-component elm