Polymer 2.x: 在 ES6 web 组件中包装外部 JS 库

Polymer 2.x: Wrapping external JS library in ES6 web component

我正在尝试使用 Polymer 2.0 将 the progressbar.js library 包装在 ES6 网络组件中。

我收到以下错误消息。

console.error

render-status.html:54
Uncaught TypeError: ProgressBar.SemiCircle is not a constructor
at HTMLElement.animateCircle (progress-bar.html:108)
at HTMLElement. (progress-bar.html:85)
at callMethod (render-status.html:51)
at runQueue (render-status.html:42)
at render-status.html:29

Here is a working JSFiddle 下面的代码我试图包裹在 Polymer 元素中。

src/progress-bar.html
<link rel="import" href = "../bower_components/polymer/polymer-element.html">
<link rel="import" href = "shared-styles.html">
<link rel="import" href = "progressbar-js.html">

<dom-module id="progress-bar">
  <template>
    <style include="shared-styles">
      :host {
        display: block;
        padding: 10 px;
      }
      p {
        font - size: 200 % ;
        font - family: Roboto, Open Sans, sans - serif;
      }
      .label {
        color: #6FD57F !important;
        font-size: 300%;
        font-family: Roboto, Open Sans, sans-serif;
      }
      #container {
        width: 200 px;
        height: 100 px;
      }
    </style>

    <div class="card">
      <div class="circle">1</div>
      <div id="container"></div>
      [[animatePercentage]]
      <p>1,234 steps</p>
    </div>
  </template>

  <script>
    class ProgressBar extends Polymer.Element {
      static get is() {
        return 'progress-bar';
      }

      static get properties() {
        return {
          animatePercentage: {
            type: Number,
            notify: true,
            value: 0.7,
          },
        }
      }

      constructor() {
        super();
      }

      ready() {
        super.ready();
        Polymer.RenderStatus.afterNextRender(this, function() {
          //...
        });
      }

      connectedCallback() {
        super.connectedCallback();
        this.animateCircle('container', this.animatePercentage);
      }

      animateCircle(containerId, animatePercentage) {
        var startColor = '#FC5B3F';
        var endColor = '#6FD57F';

        var element = document.getElementById(containerId);
        var circle = new ProgressBar.SemiCircle(element, {
          color: startColor,
          trailColor: '#eee',
          trailWidth: 5,
          duration: 2000,
          easing: 'bounce',
          strokeWidth: 5,
          text: {
            value: (animatePercentage * 100) + '%',
            className: 'label'
          },
          // Set default step function for all animate calls
          step: function(state, circle) {
            circle.path.setAttribute('stroke', state.color);
          }
        });

        circle.animate(animatePercentage, {
          from: {
            color: startColor
          },
          to: {
            color: endColor
          }
        });
      }

    }

    window.customElements.define(ProgressBar.is, ProgressBar);
  </script>
</dom-module>
src/progressbar-js.html
<script src="../bower_components/progressbar.js/dist/progressbar.min.js" charset="utf-8"></script>

此问题是由于您的 ProgressBar class 与 progressbar.js 添加的 ProgressBar 符号之间的名称冲突引起的。重命名您的 class(例如,重命名为 MyProgressBar)将解决您看到的错误。

附带说明一下,animateCircle() 使用 document.getElementById(containerId) 获取容器元素,但该方法无法查询元素的阴影 DOM,这是元素所在的位置。您可以使用此 Polymer shorthand 轻松解决此问题:this.$[containerId].

// var element = document.getElementById(containerId); // DON'T DO THIS
var element = this.$[containerId]; // DO THIS
var element = this.shadowRoot.getElementById(containerId); // OR DO THIS

demo