Использование Angular привязки свойств к компонентам, встроенным в StencilJS - PullRequest
0 голосов
/ 11 марта 2020

Я пытаюсь интегрировать WebComponents, встроенные в Stencil, в приложение Angular. Таким образом, я бы хотел, чтобы использование компонента выглядело как "angular -подобный", насколько это возможно. Начиная с очень простого компонента с парой строковых свойств, я хотел бы встроить его в мое приложение Angular обычным способом, но, кажется, зашли в тупик. Обратите внимание, что мой фактический компонент намного сложнее, чем этот, но я хотел, чтобы это было достаточно просто, чтобы кто-то мог переварить.

Мой компонент трафарета выглядит так:

import { Component, Prop, h } from '@stencil/core';

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true
})
export class MyComponent {
  @Prop() first: string;
  @Prop() last: string;

  private getText(): string {
    return `${this.first} ${this.last}`;
  }

  render() {
    return <div>Hello, World! I'm {this.getText()}</div>;
  }
}

Я публикую sh этот компонент в репозитории npm, а затем в другом каталоге создаю новое (очень простое) приложение Angular (используя angular -cli) и npm установить компонент в это приложение angular. Затем я выполняю обычные обновления до main.ts (чтобы вызвать определенныеCustomElements) и app.module.ts (чтобы импортировать CUSTOM_ELEMENTS_SCHEMA), чтобы включить WebComponents (подробности, которые я здесь опущу) Достаточно сказать, что WebComponent правильно создается.

Затем я вставляю веб-компонент в свой angular компонент со следующей строкой в шаблоне компонента Angular и двух строковых свойствах в моем компоненте Angular с именами firstName и LastName:

<my-component [first]="firstName" [last]="lastName"></my-component>

Мой компонент получает первое и последнее свойства, заполненные undefined. Привязка свойств не работает. Чтобы заставить его работать, я должен использовать привязку атрибутов и настроить свой шаблон следующим образом:

<my-component [attr.first]="firstName" [attr.last]="lastName"></my-component>

Затем он работает как положено - с односторонней привязкой к первому и последнему свойствам в моем компоненте.

Это может показаться относительно незначительной косметикой c, но я думаю, что это имеет другие последствия. Например, если я изменяю одно из свойств (скажем, первое), чтобы иметь изменяемые параметры и параметры отражения, изменения свойства в компоненте не отражаются в angular, даже если вы используете двустороннее связывание: [(attr.first)]="firstName". Опять же, есть обходной путь, вы можете объявить событие, которое вы генерируете, со значением каждый раз, когда вы изменяете первое свойство в компоненте:

@Event({ eventName: "first-changed" }) firstChanged: EventEmitter;

Изменение шаблона выглядит так:

<my-component [attr.first]="firstName" [attr.last]="lastName"> (first-changed)="onFirstChanged($event.detail)</my-component>

И, наконец, вы бы изменили компонент Angular, чтобы иметь функцию onFirstChanged:

onFirstChanged(change: string) {
  this.firstName = change;
}

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

Что особенно странно для меня, так это то, что я могу использовать примеры Google по всему Интернету, показывающие Angular встраивание компонентов трафарета, которые используют привязку свойств (и даже один, показывающий двустороннюю привязку), но я не могу ничего сделать из них фактически работают с последними кодами Stencil JS (версия 1.8.8) и Angular (версия 9.0.5).

Есть ли здесь что-то простое, что мне не хватает? Я относительно новичок во всем этом, поэтому любые рекомендации, которые вы можете дать, которые помогут мне разработать веб-компоненты, которые хорошо работают в Angular (но все еще функционируют в React и только в обычном HTML / JS), будут оценены.

...