Реализовать связь между двумя несвязанными компонентами в Stencil и js диаграммы с эмиттерами событий

Почему трафарет

Stencil — это не фреймворк, как React, Angular или Vue, это просто компилятор, который генерирует веб-компоненты, которые можно использовать внутри приложений, созданных с любыми популярными фреймворками или без них.

Веб-компоненты Stencil проще в использовании и, как правило, более эффективны, чем ванильные веб-компоненты, но сначала их необходимо скомпилировать для работы, тогда как ванильные веб-компоненты являются нативными и поэтому могут работать без какой-либо компиляции.

Установка трафарета

Вам нужно установить LTS узла и npm. Затем для установки трафарета запустите

npm install @stencil/core@latest — save-exact

затем вы можете инициализировать проект

npm init stencil

Тогда вы увидите

? Pick a starter › — Use arrow-keys. Return to submit.
 ionic-pwa Everything you need to build fast, production ready...
 app Minimal starter for building a Stencil app or website
 ❯ component Collection of web components that can be used anywhere

Вы можете выбрать между ionic-pwa, приложением и компонентом, выбрать компонент.

Что мы будем строить

Мы создадим простое приложение с выбором, которое вы можете использовать для выбора набора данных и диаграммы, построенной с помощью chartjs.

Есть два компонента: селектор набора данных и контейнер диаграммы.

Создание наших компонентов

Вы можете легко генерировать компоненты с помощью командной строки, используя

npm run generate dataset-selector
npm run generate chart-container

Селектор набора данных

Этот компонент содержит конфигурацию и данные наборов данных, здесь мы увидим эмиттеры событий в действии, каждый раз, когда вы меняете элемент в select, компонент генерирует событие, содержащее данные, это событие прослушивается компонентом контейнера диаграммы, который он получает данные, и он будет отображать диаграмму в соответствии с этими данными.

Создать событие из компонента трафарета легко, это можно сделать всего парой строк

// define the ebent object
@Event() private changedDataset: EventEmitter<any>;
...
// emit the event with data
this.changedDataset.emit(myData);

myData может быть чем угодно, строкой, Json, массивом...

Функция, которая специально отправляет данные в компонент диаграммы на основе выбранного набора данных, выглядит следующим образом:

private changedDatasetEvent = (event: any) => {
  if(event.path[0].selectedIndex === 0) {
    this.data.datasets[0].data = [0, 10, 5, 2, 20, 30, 45];
    this.data.datasets[0].label = "My First Dataset";
  } else if (event.path[0].selectedIndex === 1) {
    this.data.datasets[0].data = [30, 20, 40, 45, 20, 3, 10];
    this.data.datasets[0].label = "My Second Dataset";
  } else {
    this.data.datasets[0].data = [10, 10, 15, 12, 120, 130, 145];
    this.data.datasets[0].label = "My Third Dataset";
  }
  this.changedDataset.emit(this.config); // now correct this
}

Контейнер диаграммы

Этот компонент содержит диаграмму, чтобы использовать диаграмму js, сначала нам нужно импортировать библиотеку диаграмм и зарегистрировать ее элементы в компоненте диаграммы-контейнера.

import { Chart, registerables } from 'chart.js';
...
constructor() {
  Chart.register(...registerables);
}

Теперь мы можем использовать диаграмму js.

Чтобы поместить диаграмму на наш холст, сначала мы создаем объект, представляющий общий элемент html.

@Element() private element: HTMLElement;

Затем мы указываем на наш холст с помощью метода querySelectorAll, когда компонент загружается.

componentDidLoad() {
  this.myChartRef =    this.element.shadowRoot.querySelectorAll('canvas.myChart');
}

теперь мы можем использовать this.myChartRef в качестве эталонного холста для вставки диаграммы, тогда как this.myChart является ссылкой на диаграмму.

this.myChart = new Chart(
  this.myChartRef,
  event.detail
);

последний шаг — заставить компонент контейнера диаграммы прослушивать событие, испускаемое компонентом селектора набора данных, и отображать новый набор данных, мы можем добиться этого с помощью этого кода.

@Listen('changedDataset', { target: 'window' })
changedDatasetEventHandler(event: any) {
  if(this.myChart !== undefined) {
    this.myChart.destroy();
  }

  this.myChart = new Chart(
    this.myChartRef,
    event.detail
  );
}

где changeDataset — это событие, поступающее от компонента селектора набора данных.

Получить код

Чтобы получить полный код, перейдите сюда: CertosinoLab/mediumarticles at stencil-1 (github.com)

Спасибо за чтение!