OnChange не срабатывает в поле ввода litElement - PullRequest
0 голосов
/ 25 апреля 2020

У меня есть следующий код:

export class ViTextfield extends LitElement 
{
static get properties() {
    return { 
        value: { type: String }, 
  }

 onChange(e) { console.log(e.target.value) }

 render()
{
    return html`
    <div>

        <div>
            <input id="vi-input" 
                type="text" 
                value="${this.value}"
                @change=${this.onChange} />
        </div>
    </div>
        `
}

Так что все работает нормально для себя. Теперь разработчик, использующий мой компонент, должен иметь возможность установить значение с помощью свойства, например

  document.getElementById('myComponent').value = 1;

. Теперь возникает 2 проблемы: 1) само значение не обновляется и 2) onchange не запускается

Проблема 1 Я исправил с изменением

value="${this.value}"

на

.value="${this.value}"

, даже я не знаю, почему это работает (нашел этот взлом онлайн).

Но все же onChange не стреляет ...

1 Ответ

2 голосов
/ 27 апреля 2020

Код не работает так, как вы ожидаете, из-за нескольких вещей:

  1. Почему value не работает, когда .value работает?

lit- html использует точку здесь для различения guish между назначением атрибута значения или свойства (value назначает атрибут и .value свойство)

Самый простой способ думать о том, что это те атрибуты, которые установлены на самом HTML, а свойства установлены на объекте Javascript, который представляет этот узел.

Теперь, это важно в этом случае, потому что свойство value элемент input устанавливается только из атрибута при первом его рендеринге, если вы хотите изменить его позже, вы должны установить свойство, а не атрибут. Источник

Почему событие изменения не вызывается, когда свойство значения изменяется из кода?

Это происходит потому, что событие изменения запускается из входа, только когда значение входа изменилось из-за какого-то пользователя вход. Источник

Если вы хотите иметь какой-то побочный эффект, который запускается не только при взаимодействии пользователя при вводе, но также при изменении свойства в коде, вы, вероятно, захотите использовать сеттер. В вашем случае это будет выглядеть так:

export class ViTextfield extends LitElement {
  static get properties() {
    return {
      value: {
        type: String
      },
    }
  }

  set value(value) {
    const oldValue = this.value;
    // do some side effect here        
    // set a pseudo-private property that will contain the actual value
    this._value = value;
    // call LitElement's requestUpdate so that a rerender is done if needed
    this.requestUpdate('value', oldValue);
  }

  get value() {
    // return the pseudo-private so that when vitextfield.value is accessed the correct value is returned
    return this._value;
  }

  onChange(e) {
    // update the property so that it keeps up with the input's current value
    this.value = e.target.value;
  }

  render() {
    return html `
    <div>
        <div>
            <input id="vi-input" 
                type="text" 
                value="${this.value}"
                @change=${this.onChange} />
        </div>
    </div>
        `
  }
}

Для получения дополнительной информации проверьте эту часть руководства LitElement

...