如何使用litElement在另一个组件中获得组件状态更改?

时间:2019-06-22 20:35:52

标签: typescript custom-component state-management lit-element lit-html

我基于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>
    `;
  }
}

如您所见,我们有两个组成部分:我的表单

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" />
    `;
  }
}

和我的看法:

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>
    `;
  }
}

要获取属性countmy-form变为my-view,我调度了事件侦听器,然后在my-app使用了它,然后在handleCountChange使用了将count的{​​{1}}值作为{class}导入为类,并将其作为组件导入。

当前,这可行,但是我觉得这还有很长的路要走,特别是当我有更多的嵌套组件时。我想知道这样做是否更好。 是否有与MyView中存在的Context API类似的东西 我曾考虑过使用react.js,但有人不建议使用litElemnt。 我正在考虑的想法之一是将事件调度到redux而不是当前组件,但这可能是一个不好的做法!您有什么建议,请告诉我?

1 个答案:

答案 0 :(得分:1)

您可能已经解决了此问题,但是我可以向您发送如何处理此问题。

您需要将状态提升到my-app组件。此状态将是事实的唯一来源,并将count值传递给my-formmy-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组件。没有它,它也可以工作,但是如果您这样做,您将失去状态的唯一真实来源,并且可能导致潜在的意外行为。

如果您需要发送示例,请告诉我。