问题总结 我在 elm 0.19.1 中使用 webcomponents。目标是让 webcomponent 在 webcomponent 属性“requeststate”发生变化时发出一个事件。事件被发出(我可以在 webcomponent 构造函数的日志中看到),但 elm 没有正确触发“WebcomponentEvent”。问题出在 windows 10 和 ubuntu 16.04、firefox 和 chrome 上。没有测试旧的 elm 版本。
重现步骤:
打开 elm-debugger 或再次单击“请求”按钮将神奇地在 elm 中触发事件。奇怪的。我也做了分支'tom-experiment'。在这个分支中,我从 webcomponent-click 工作中获得了事件,但前提是我直接点击了 webcomponent 本身。
这个问题的重要性 为什么我要通过改变一个属性来触发一个webcomponent上的事件?这种方法的目标也是 JavaScript 互操作。例如,我现在可以使用这个 webcomponent 来创建日期时间或 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")
] []
]
Run Code Online (Sandbox Code Playgroud)
这是 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);
Run Code Online (Sandbox Code Playgroud)
这是我的 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>
Run Code Online (Sandbox Code Playgroud)
这是在 Elm Slack 上讨论的。该问题最终成为时间问题。决议是从
this.dispatchEvent(customEvent)
Run Code Online (Sandbox Code Playgroud)
到
requestAnimationFrame(() => this.dispatchEvent(customEvent))
Run Code Online (Sandbox Code Playgroud)
在自定义元素中,可以在这个 ellie https://ellie-app.com/cqGkT6xgwqKa1 中看到。
感谢@antew 提供最终解决方案。
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |