首页 文章

如何在视图加载时运行SystemJs模块

提问于
浏览
0

我有一个组件,它加载一个构建在Bootstrap.js和Jquery上的javascript模块,以自动为基于H1,H2,...标头的页面构建一个目录 . 组件代码如下:

import { bindable, bindingMode, customElement, noView } from 'aurelia-framework';

@noView()
@customElement('scriptinjector')
export class ScriptInjector {
  @bindable public url;
  @bindable public isLocal;
  @bindable public isAsync;
  @bindable({ defaultBindingMode: bindingMode.oneWay }) protected scripttag;
  private tagId = 'bootTOCscript';

  public attached() {
    if (this.url) {
      this.scripttag = document.createElement('script');
      if (this.isAsync) {
        this.scripttag.async = true;
      }
      if (this.isLocal) {
        System.import(this.url);
        return;
      } else {
        this.scripttag.setAttribute('src', this.url);
      }
      document.body.appendChild(this.scripttag);
    }
  }

  public detached() {
    if (this.scripttag) {
      this.scripttag.remove();
    }
  }
}

对于那些不熟悉Aurelia的人来说,这只是使用SystemJs从我的app-bundle加载bootstrap-toc.js模块,无论我把它放在我的视图上:

<scriptinjector url="lib/bootstrap-toc.js" is-local.bind='true'></scriptinjector>

我的问题是,虽然这在我第一次加载视图时效果很好,但后续访问不会生成TOC(目录) . 我已经检查过Aurelia实际上每次加载视图时都调用System.Import,但似乎一旦模块被导入一次,它就永远不会再次导入(来自bundle的代码永远不会再次运行) .

当我重新进入视图时,有谁知道如何卸载/重新加载/重置/重新运行模块?

1 回答

  • 0

    好吧,经过几天的斗争,我找到了一个可接受的解决方案,它保留了TOC库的所有功能,并且需要尽可能少地修改骨架项目和目标库 . 忘记上面的脚本注入器 .

    在index.html中,执行以下操作:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8">
        <title>Holdings Manager</title>
        <!--The FontAwesome version is locked at 4.6.3 in the package.json file to keep this from breaking.-->
        <link rel="stylesheet" href="jspm_packages/npm/font-awesome@4.6.3/css/font-awesome.min.css">
        <link rel="stylesheet" href="styles/styles.css"> 
        <meta name="viewport" content="width=device-width, initial-scale=1">
      </head>
    
      <body aurelia-app="main" data-spy="scroll" data-target="#toc">
        <div class="splash">
          <div class="message">Holdings Manager</div>
          <i class="fa fa-spinner fa-spin"></i>
        </div>
    
        <!-- The bluebird version is locked at 4.6.3 in the package.json file to keep this from breaking -->
        <!-- We include bluebird to bypass Edge's very slow Native Promise implementation. The Edge team -->
        <!-- has fixed the issues with their implementation with these fixes being distributed with the  -->
        <!-- Windows 10 Anniversary Update on 2 August 2016. Once that update has pushed out, you may    -->
        <!-- consider removing bluebird from your project and simply using native promises if you do     -->
        <!-- not need to support Internet Explorer.                                                      -->
        <script src="jspm_packages/system.js"></script>
        <script src="config.js"></script>
        <script src="jspm_packages/npm/bluebird@3.4.1/js/browser/bluebird.min.js"></script>
        <script src="jspm_packages/npm/jquery@2.2.4/dist/jquery.min.js"></script>
        <script src="jspm_packages/github/twbs/bootstrap@3.3.7/js/bootstrap.min.js"></script>
        <script>
          System.import('core-js').then(function() {
            return System.import('polymer/mutationobservers');
          }).then(function() {
            System.import('aurelia-bootstrapper');
          }).then(function() {
            System.import('lib/bootstrap-toc.js');
          });
        </script>
    
      </body>
    </html>
    

    这假设你已经使用jspm安装了bootstrap(它将jquery作为依赖项引入) . 这也假设您已将javascript库(您要合并的那个,我的情况下是bootstrap-toc)放在src / lib文件夹中,并且您有configured your bundling来包含源文件夹中的js文件 .

    接下来,如果您的库具有定义的自执行匿名函数,则需要获取该代码并将其移动到您希望应用库的viewmodel的“附加”方法中 . 所以在这种情况下,我有一个“帮助”视图,其中包含我想要为其生成TOC的一些部分/子部分,因此代码如下所示:

    import { singleton } from 'aurelia-framework';
    
    @singleton()
    export class Help {
      public attached() {
          $('nav[data-toggle="toc"]').each((i, el) => {
            const $nav = $(el);
            window.Toc.init($nav);
          });
      }
    }
    

    上面'附加'方法中的代码是从bootstrap-toc.js文件中剪切并粘贴的,我删除了自执行的匿名方法 .

    我尝试将system.import用于jquery / bootstrap库,但这使得TOC功能的一部分停止工作,我已经失去了耐心去弄清楚为什么这些库现在作为脚本引用保留 .

    此外,当您构建项目时,您将收到错误:

    help.ts(7,7): error TS2304: Cannot find name '$'.
    help.ts(9,16): error TS2339: Property 'Toc' does not exist on type 'Window'.
    

    这些不会在运行时导致问题,因为$和Toc都将在视图实例化之前定义 . 您可以使用此解决方案解决这些构建错误here .

相关问题