如何同步渲染嵌入式Elm模块?

时间:2016-09-25 14:12:05

标签: elm

我正在尝试嵌入" HelloWorld"模块进入现有的HTML页面。 我发现模块是异步渲染的(我没有得到渲染元素 在致电"嵌入")后立即。

我想在现有项目中使用Elm并重写JavaScript的某些部分 在榆树。但异步渲染会让事情变得困难。

有没有办法同步渲染它?

的index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="app.js" type="text/javascript"></script>
</head>
<body>
<script type="text/javascript">
    var appContainer = document.createElement('div');
    Elm.HelloWorld.embed(appContainer);
    console.log('Html: ' + appContainer.innerHTML); // Will print an empty string
    setTimeout(function() {
        console.log('Html: ' + appContainer.innerHTML); // Will print "Hello, World!"
    }, 0);
</script>
</body>
</html>

HelloWorld.elm

module HelloWorld exposing (main)

import Html exposing (text)

main =
  text "Hello, World!"

UPD:删除了多余的代码。

1 个答案:

答案 0 :(得分:1)

如今,榆树并没有暴露这种钩子。 您基本上有两种不同的方法,一种基于事件,另一种基于计时(您已经使用的setTimeout()方法)。

事件驱动的方法涉及MutationObserver Api

创建一个新的MutationObserver,您可以观察运行Elm模块的HTML节点:这样,您就可以在DOM更新上找到一个钩子。

天真的检查将检查孩子的appContainer列表:

<body>
<div id="myDiv"></div>
<script type="text/javascript">
    var appContainer = document.getElementById('myDiv');
    var mo = new MutationObserver(function(mutationRecords, instance) {
        for (var i = 0; i < mutationRecords.length; i += 1) {
            if (mutationRecords[i].addedNodes.length > 0) {
                // a trivial check
                console.log('Html: ' + appContainer.innerHTML);
                // stop observing, if not needed anymore
                mo.disconnect();
            }
        }
    });
    mo.observe(appContainer, { childList: true });
    Elm.HelloWorld.embed(appContainer);
</script>
</body>

请注意,上面的代码假设您的 HelloWorld 模块正在向appContainer添加子项,因此您应该方便地修改它:

module HelloWorld exposing (main)

import Html exposing (p, text)

main =
  p [] [ text "Hello, World!" ]