如何在 mithril.js 中使用另一个 js

问题描述

我需要在我的网站中包含一个第三方 js 库,一个纯 HTML 文件中的工作示例类似于

<div id="app"></div>
<script src="app.js"></script>
<script>App.initialize();</script>

initialize() 函数基本上会先用加载动画填充 #app,然后从外部 API 获取数据,最后用它生成的 html 代码加载 #app

一切正常,直到我用 mithril.js 重写它,比如

const page = {
  view: () => [
    m('script',{src: 'app.js'}),m(app)
  ]
} 
const app = {
  oncreate: () => { App.initialize();},view: () => m('#app')
}

当我渲染 page 时,我仍然可以看到加载动画,但在它消失后,#app 中没有任何显示#app 中没有像在纯 HTML 文件中那样加载预期的代码,并且控制台中没有错误消息。

我是否在 mithril.js 中遗漏了什么或做错了什么?

解决方法

我认为以这种方式加载脚本可能存在某种计时问题。此外,如果它将东西放入 body 元素中,那么 mithril 可能会重新渲染它。也许尝试这样的事情:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf8">
    </head>
    <body>
        <script src="https://unpkg.com/mithril/mithril.js"></script>
        <div id="page"></div>
        <script type="text/javascript">
         let appLoaded = false;
         let mithrilLoaded = false;
         let appTimer = null;
         let mithrilTimer = null;
         function stopSync() {
             console.log('Sync done,init app.')
             appLoaded = mithrilLoaded = true;
             window.clearInterval(appTimer);
             window.clearInterval(mithrilTimer);
             appTimer = mithrilTimer = null;
             App.initialize();
         }
         function startAppSync() {
             console.log('App loaded,start sync with mithril.')
             appLoaded = true;
             appTimer = window.setInterval(checkAppSync,100);
         }
         function startMithrilSync() {
             console.log('Mithril loaded,start sync with app.')
             mithrilLoaded = true;
             mithrilTimer = window.setInterval(checkMithrilSync,100);
         }
         function checkAppSync() {
             console.log('Checking mithril from app sync.')
             if (mithrilLoaded) {
                 stopSync();
             }
         }
         function checkMithrilSync() {
             console.log('Checking app from mithril sync.')
             if (appLoaded) {
                 stopSync();
             }
         }
         const page = {
             view: function() {
                 return m('',[
                     m('script',{
                         onload: function () {
                             startAppSync();
                         },src:'app.js'
                     }),m(app),]);
             }
         }
         const app = {
             oncreate: function() {
                 startMithrilSync();
             },view: function() {
                 return m('#app');
             }
         }

         m.mount(document.getElementById('page'),page);
        </script>
    </body>
</html>

这里有更多信息,注入的脚本默认是异步加载的。您可以在浏览器中使用 document.createElement('script').async 进行测试。

https://developer.mozilla.org/en-US/docs/Web/API/HTMLScriptElement#dynamically_importing_scripts