Tengo un problema con dos componentes web creados con lit-element v3.2.0 y estoy usando eventos personalizados para emitir el valor de entrada desde el componente secundario hasta el componente principal.
El componente de entrada de formulario es una entrada reutilizable que extrae el valor de entrada y lo emite al componente principal con un evento personalizado llamado "nuevo valor" que se envía cuando el usuario escribe en el campo.
El componente de contenedor de formulario contiene la entrada de formulario, aquí estoy vinculando el evento personalizado "nuevo valor" a un método llamado "updateInputValue" que debería reasignar la propiedad inputValue con el valor emitido del componente secundario, pero en su lugar es pegado con cualquier valor inicializado en el constructor principal.
formulario-contenedor.js
static get properties() { return { inputValue: { type: String }, items: { type: Array }, } } constructor() { super() this.inputValue = '' this.items = [] } render() { return html`<form> <h1>My form container</h1> <form-input @new-value=${this.updateInputValue} fieldName="name" id="name" label="Name" placeholder="Enter anything" value="${this.inputValue}" ></form-input> <button @click=${this.addNewItem} type="submit">Add</button> <form-list .items="${this.items}"></form-list> </form>` } updateInputValue(e) { // Update input value with the value emitted from the form-input this.inputValue = e.detail } addNewItem(e) { // Add new item to the list e.preventDefault() console.log('add new item with the following value:', this.inputValue)formulario-entrada.js
static get properties() { return { value: { type: String }, fieldName: { type: String }, label: { type: String }, placeholder: { type: String }, type: { type: String }, } } constructor() { super() } render() { return html` <div> <label for="name">${this.label}</label> <input @input=${this.dispatchEvent} id="${this.fieldName}" name="${this.fieldName}" placeholder="${this.placeholder}" type="${this.type || 'text'}" value="${this.value}" /> </div> ` } dispatchEvent(e) { // Emit the new value from the input to the parent component const target = e.target if (target) { this.dispatchEvent( new CustomEvent('new-value', { detail: target.value, }) ) } }Cualquier ayuda será muy apreciada.
Está sobrescribiendo el método dispatchEvent y llamándose a sí mismo. Cambie el nombre del método dispatchEvent y asígnele un nombre significativo. Funciona perfectamente.
<script type="module"> import { LitElement, html, css } from "https://unpkg.com/lit-element/lit-element.js?module"; class FormInput extends LitElement { static get properties() { return { value: { type: String }, fieldName: { type: String }, label: { type: String }, placeholder: { type: String }, type: { type: String }, }; } render() { return html` <div> <label for="name">${this.label}</label> <input @input=${this.changedInput} id="${this.fieldName}" name="${this.fieldName}" placeholder="${this.placeholder}" type="${this.type || 'text'}" value="${this.value}" /> </div> ` } changedInput(e) { // Emit the new value from the input to the parent component console.log(e.target.value); const myevent = new CustomEvent('my-event', { bubbles: true, composed: true, detail: { value: e.target.value } }) this.dispatchEvent( myevent ); } } class FormContainer extends LitElement { static get properties() { return { name: { inputValue: { type: String }, } }; } updateInputValue(e) { console.log('received ' + e.detail.value); this.inputValue = e.detail.value; } addNewItem(e) { // Add new item to the list e.preventDefault() console.log('add new item with the following value:', this.inputValue); } render() { return html`<form> <h1>My form container</h1> <form-input @my-event="${this.updateInputValue}" fieldName="name" id="name" label="Name" placeholder="Enter anything" value="${this.inputValue}" ></form-input> <button @click=${this.addNewItem} type="submit">Add</button> <form-list .items="${this.items}"></form-list> </form> `; } } customElements.define("form-container", FormContainer); customElements.define("form-input", FormInput); </script> <form-container></form-container>