Синхронизация атрибутов и свойств

В FAST Element управление состоянием компонентов основано на концепции реактивных свойств и синхронизации их с HTML-атрибутами. Это позволяет создавать гибкие и динамичные веб-компоненты, где изменения в DOM автоматически отражаются в логике компонента и наоборот.

Реактивные свойства

Основой синхронизации являются реактивные свойства, которые определяются через декоратор @attr или с использованием статического свойства observedAttributes. Реактивное свойство автоматически отслеживает изменения, происходящие через DOM-атрибуты, и обновляет внутреннее состояние компонента.

Пример декларации реактивного свойства через @attr:

import { FASTElement, html, css, attr } from "@microsoft/fast-element";

class MyElement extends FASTElement {
    @attr color;  // Атрибут color автоматически синхронизируется со свойством
}

При этом:

  • Изменение свойства element.color = "red" автоматически обновляет атрибут <my-element color="red">.
  • Изменение атрибута element.setAttribute("color", "blue") обновляет свойство element.color.

Типизация и преобразование значений

FAST Element позволяет задать типы и конвертеры значений для атрибутов, чтобы автоматически преобразовывать строковое значение HTML-атрибута в необходимый тип JavaScript.

Пример с булевым значением:

class ToggleButton extends FASTElement {
    @attr({ mode: "boolean" }) pressed;
}

Особенности:

  • Атрибут <toggle-button pressed> будет интерпретироваться как true.
  • Отсутствие атрибута или pressed="false" преобразуется в false.
  • Присвоение свойства pressed = true добавляет атрибут в DOM.

Режимы синхронизации атрибутов

FAST Element поддерживает несколько режимов синхронизации атрибутов:

  1. reflect — свойство отражает изменение в атрибуте.
  2. boolean — автоматическое преобразование строковых значений в булевы.
  3. number — преобразование строкового значения в число.
  4. custom — пользовательские конвертеры через converter:
@attr({
    converter: {
        fromView(value) {
            return parseInt(value, 10);
        },
        toView(value) {
            return value.toString();
        }
    }
})
count;

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

Свойства без синхронизации с атрибутами

Не все свойства компонента должны быть связаны с атрибутами. Для внутренних состояний используется обычная реактивная декларация свойства без @attr. Такие свойства реагируют на изменения через механизм обновления шаблона, но не отражаются в DOM.

class Counter extends FASTElement {
    count = 0; // только внутреннее состояние
}

Обработка изменений свойств

FAST Element предоставляет хуки для реакции на изменении свойств:

  • propertyChangedCallback(name, oldValue, newValue) — вызывается при каждом изменении свойства.
  • @observable — можно использовать для декларации наблюдаемых свойств, которые не обязательно синхронизируются с атрибутами.

Пример:

import { observable } from "@microsoft/fast-element";

class MyElement extends FASTElement {
    @observable value;

    valueChanged(oldValue, newValue) {
        console.log(`Значение изменилось с ${oldValue} на ${newValue}`);
    }
}

Синхронизация с шаблоном

Свойства FAST Element тесно связаны с шаблоном компонента, где их изменения автоматически приводят к обновлению DOM. Например:

const template = html<MyElement>`
    <div style="color: ${x => x.color}">
        Текущий цвет: ${x => x.color}
    </div>
`;

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

Практические рекомендации

  • Использовать @attr для свойств, которые должны быть доступны через DOM и конфигурируемы через HTML.
  • Применять типы и конвертеры для автоматической трансформации данных.
  • Разделять внутренние свойства (@observable или обычные) и свойства, синхронизируемые с атрибутами, чтобы избежать лишней нагрузки на DOM.
  • В шаблонах использовать прямую привязку к свойствам для реактивного обновления интерфейса.

Синхронизация атрибутов и свойств в FAST Element обеспечивает мощный и гибкий механизм для построения реактивных веб-компонентов с минимальной ручной работой, упрощая поддержку согласованного состояния между DOM и логикой JavaScript.