LitElement получает обновленное значение атрибута, когда для свойства установлено новое значение

Я хочу, чтобы атрибут обновлялся, когда для свойства было установлено новое значение. так что я сделал, чтобы позвонить element.requestUpdate() так что я могу получить обновленный атрибут, но requestUpdate является асинхронным. Есть ли другой способ получить обновленный атрибут без вызова requestUpdate? URL Stackblitz => https://stackblitz.com/edit/typescript-nojnqa

LitElement получает обновленный атрибут

1 ответ

Решение

Свойства и атрибуты

На самом деле вам не нужно вручную обновлять атрибуты при изменении свойств: lit-element имеет встроенную функциональность для отражения изменений свойств в атрибутах.

Из документации:

Вы можете настроить свойство таким образом, чтобы при каждом изменении его значение отражалось в наблюдаемом атрибуте. Например:

// Value of property "myProp" will reflect to attribute "myprop"
myProp: { reflect: true }

В вашем примере вы уже используете reflect: true но вы объявляете свойства с помощью нотации JS в среде TS.

Это:

static get properties() {
  return {
    name: {
      type: String,
      reflect: true
    }
  }
}

должно быть так:

@property({
  reflect: true,
})
name: string;

тайминг

Тогда есть небольшая проблема со временем. Этот код, который вы положили в index.html:

<script>
  (async function() {
    const element = document.querySelector('#app').querySelector('hello-name')
    element.name = 'Maria'
    await element.requestUpdate()

    console.log(element.getAttribute('name')) //// result => Maria
  })()
</script>

запускается после того, как пользовательский элемент добавляется в dom, но до инициализации логики свойств LitElement. Если вы попытаетесь отложить выполнение этого кода, вы обнаружите, что отражение атрибута свойства LitElement будет работать, как и ожидалось.

Жду обновления

призвание element.requestUpdate() не нужно, потому что сеттер element.name = ... уже звонит requestUpdate() под капотом.

Для такого сценария LitElement имеет геттер, updateComplete это возвращает обещание, которое разрешается после завершения цикла обновления.

element.name = 'Maria';
await element.updateComplete;
console.log(element.getAttribute('name')); // Maria

И наконец, если ваша проблема связана с использованием async / await Есть ряд альтернатив:

  • замена async / await с Promise#then()/catch(),
  • с помощью setImmediate() / setTimeout() дождаться окончания обновления микрозадачи,
  • увольнение Event когда атрибут изменился.

Вот вилка вашего StackBlitz с возможным решением.

Другие вопросы по тегам