Polymer 2.x: включение внешней JS-библиотеки в веб-компонент ES6

Я пытаюсь обернуть библиотеку progressbar.js внутри веб-компонента ES6, используя Polymer 2.0.

Я получаю следующее сообщение об ошибке.

console.error

render-status.html:54
Uncaught TypeError: ProgressBar.SemiCircle не является конструктором
в HTMLElement.animateCircle (progress-bar.html:108)
в HTMLElement. (progress-bar.html:85)
в callMethod (render-status.html:51)
в runQueue (render-status.html:42)
в render-status.html:29

Вот рабочий 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>

person Let Me Tink About It    schedule 20.05.2017    source источник
comment
Не потому ли, что вы определяете новый класс/прототип ProgessBar: class ProgressBar extends Polymer.Element {, а затем пытаетесь вызвать метод, который «больше не существует» new ProgressBar.SemiCircle?   -  person Booster2ooo    schedule 20.05.2017
comment
@Booster2ooo: Я думаю об этом. Мне интересно, нужно ли мне импортировать поведение? Я думал, что link import будет достаточно. Есть ли у вас какие-либо предложения по правильному способу сделать это?   -  person Let Me Tink About It    schedule 20.05.2017
comment
Я не очень хорошо разбираюсь в веб-компонентах, поэтому могу ошибаться, но все же вот что я вижу. Вы импортируете библиотеку progressbar.js, которая определяет ProgressBar прототип/класс, который можно использовать для создания фигур: new ProgressBar.SemiCircle. Но затем, после импорта этой библиотеки, вы говорите, хорошо, теперь ProgressBar будет новым прототипом/классом, который расширяет Polymer.Element, уничтожая предыдущий, который вы загрузили. Итак, он попадает в animateCircle и new ProgressBar.SemiCircle, SemiCircle больше не существует. Вы должны попробовать переименовать свой класс в PolymerProgressBar, чтобы избежать подобных проблем.   -  person Booster2ooo    schedule 20.05.2017
comment
Кроме того, я не знаю, предназначено ли это, но вы загружаете файл HTML, а не файл JS для индикатора выполнения: <link rel="import" href = "progressbar-js.html">   -  person Booster2ooo    schedule 20.05.2017
comment
@ Booster2ooo: я отредактировал вопрос, чтобы было ясно, что я импортирую библиотеку JS через html-файл в соответствии с рекомендуемой передовой практикой.   -  person Let Me Tink About It    schedule 20.05.2017
comment
просто предположение, но может быть, вы где-то используете AMD или CommonJs? // Если вы не используете какой-либо загрузчик модулей, progressbar.js предоставляет // глобальную переменную: window.ProgressBar => если вы используете загрузчик, я думаю, он не будет отображаться для окна?   -  person daKmoR    schedule 21.05.2017


Ответы (1)


Проблема вызвана конфликтом имен между вашим классом ProgressBar и символом ProgressBar, добавленным progressbar.js. Переименование вашего класса (например, в MyProgressBar) устранит ошибку, которую вы видите.

В качестве примечания: animateCircle() использует document.getElementById(containerId) для извлечения элемента-контейнера, но этот метод не может запрашивать теневую модель DOM элемента, в которой находится этот элемент. Вы можете легко исправить это с помощью этого сокращения Polymer: 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

демонстрация

person tony19    schedule 20.05.2017