Как я могу получить изменение состояния компонента в другом компоненте с помощью litElement? - PullRequest
0 голосов
/ 22 июня 2019

Я начал проект на основе LitElement Есть много компонентов, вложенных друг в друга. Допустим, у нас есть такая структура:

enter image description here

корневой компонент my-app

import { LitElement, html, customElement, query } from 'lit-element';
import './my-form';
import './my-view';
import { MyView } from './my-view';

@customElement('my-app')
export class MyApp extends LitElement {
  @query('my-view') private myView?: MyView;

  private handleCountChange(e: CustomEvent<{ count: number }>) {
    if (!this.myView) throw 'my-view not found!';
    this.myView.count = e.detail.count;
  }

  render() {
    return html`
      <my-form @countChanged=${this.handleCountChange}></my-form>
      <my-view></my-view>
    `;
  }
}

как видите, у нас есть два компонента: my-form

import { LitElement, html, customElement, property } from 'lit-element';

@customElement('my-form')
export class MyForm extends LitElement {
  @property({ type: Number }) count: any = 0;

  private updateCount(e: KeyboardEvent) {
    this.count = (<HTMLInputElement>e.target).value;
    this.dispatchEvent(
      new CustomEvent('countChanged', {
        composed: true,
        bubbles: true,
        cancelable: true,
        detail: { count: this.count }
      })
    );
  }

  render() {
    return html`
      <input value=${this.count} @input=${this.updateCount} type="text" />
    `;
  }
}

и my-view:

import { LitElement, html, customElement, property } from 'lit-element';

@customElement('my-view')
export class MyView extends LitElement {
  @property({ type: Number }) count: number = 0;

  render() {
    return html`
      <p>${this.count}</p>
    `;
  }
}

Чтобы получить свойство count изменяется с my-form на my-view Я отправил прослушиватель событий, затем использовал его в my-app, затем в handleCountChange Я присваиваю count значение для MyView, который импортировал в качестве класса в дополнение к импорту его в качестве компонента.

В настоящее время это работает, но я чувствую, что это долгий путь, особенно когда у меня больше вложенных компонентов. Я хотел бы знать, есть ли лучшее для этого. Есть ли что-то похожее на Context API, которое существует в react.js Я думал об использовании redux, но кто-то не рекомендовал его с litElemnt. Одна из идей, о которых я думаю, - отправить событие на document вместо текущего компонента, но, возможно, это плохая практика! Каковы ваши предложения, пожалуйста, дайте мне знать?

1 Ответ

1 голос
/ 15 июля 2019

Возможно, вы решили эту проблему, но я могу выслать вам, как с этим справиться.

Вам необходимо поднять ваше состояние до my-app компонента. Это состояние будет единственным источником правды и предоставит count значение для my-form и my-view дочерних компонентов.

В компоненте my-app вы можете изменить handleCountChange на что-то подобное (в случае, если вы определите count в качестве атрибута и разрешите my-app получить начальное значение из атрибутов):

 private handleCountChange(e: CustomEvent<{ count: number }>) {
   this.setAttribute('count', count); // If you set `count` as observed attribute, you will not need to call `requestUpdate` method
 }

или как этот, если вы определите count как свойство класса

 private handleCountChange(e: CustomEvent<{ count: number }>) {
   this.count = count;
   this.requestUpdate(); // force to call render method which is necessary in this case
 }

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

Если вам нужно будет отправить пример, пожалуйста, дайте мне знать.

...