FAST Element предоставляет мощный механизм для синхронизации атрибутов HTML с внутренними свойствами компонентов, что позволяет создавать реактивные, настраиваемые и легко управляемые веб-компоненты. Основная концепция здесь — reflection, или отражение атрибутов.
В FAST Element каждое свойство класса компонента может быть связано с
атрибутом HTML. Для этого используется декоратор @attr из
библиотеки @microsoft/fast-element. Свойство с атрибутом
автоматически:
Пример:
import { FASTElement, attr, html, css } from "@microsoft/fast-element";
class MyButton extends FASTElement {
@attr text; // отражение строки
@attr({ mode: "boolean" }) disabled; // отражение булевого значения
}
const template = html<MyButton>`
<button ?disabled="${x => x.disabled}">${x => x.text}</button>
`;
MyButton.define({ name: "my-button", template });
В этом примере:
text отражается на свойство
text.disabled синхронизируется с
соответствующим свойством и автоматически конвертируется в
true/false.FAST Element поддерживает несколько режимов отражения, задаваемых
через опцию mode:
true.Пример кастомной конверсии:
@attr({
mode: "fromView",
converter: {
fromView(value) {
return parseInt(value, 10);
},
toView(value) {
return value.toString();
}
}
})
count;
Здесь значение атрибута всегда хранится как строка в HTML, но в компоненте доступно как число.
Отражение атрибутов тесно связано с реактивностью. Любое изменение
свойства, связанного с атрибутом, инициирует автоматическое обновление
DOM. FAST Element использует механизм наблюдаемых свойств
(observable properties), что позволяет избежать ручной работы с
MutationObserver или кастомными событиями.
Пример реактивного поведения:
class Counter extends FASTElement {
@attr({ mode: "number" }) value = 0;
increment() {
this.value += 1; // автоматически обновляется атрибут и шаблон
}
}
const template = html<Counter>`
<div>Счёт: ${x => x.value}</div>
<button @click="${x => x.increment()}">+</button>
`;
Counter.define({ name: "counter-element", template });
При изменении value атрибут value на
элементе синхронизируется автоматически, а содержимое
<div> обновляется без дополнительных усилий.
Не все свойства компонента должны отражаться на атрибуты. FAST
Element позволяет создавать невидимые для HTML свойства,
которые остаются внутренними. Для этого не используется
@attr, а просто объявляется обычное свойство:
class UserCard extends FASTElement {
name; // внутреннее свойство
@attr age; // отражаемое свойство
}
Это полезно для внутренних состояний, кэширования или вычисляемых значений, которые не должны попадать в DOM.
Опции декоратора @attr позволяют детально управлять
отражением:
attribute: string — указание имени атрибута, отличного
от имени свойства.mode — тип отражения (string,
boolean, number или кастомный).converter — объект с функциями fromView и
toView.reflect — булевое значение, указывающее, нужно ли
синхронизировать свойство с атрибутом при изменении свойства (по
умолчанию true).Пример:
@attr({ attribute: "user-age", mode: "number" })
age;
Теперь свойство age синхронизируется с атрибутом
user-age вместо age.
Булевые атрибуты имеют особенность: их наличие обозначает
true, а отсутствие — false. FAST Element
автоматически учитывает это при отражении:
class ToggleSwitch extends FASTElement {
@attr({ mode: "boolean" }) checked;
}
const template = html<ToggleSwitch>`
<input type="checkbox" ?checked="${x => x.checked}">
`;
При установке checked = true в элемент добавляется
атрибут checked, при false — удаляется.
FAST Element позволяет использовать отражение атрибутов не только для
статических свойств, но и для динамически вычисляемых значений. Любое
изменение свойства, отражаемого через @attr, автоматически
вызывает реактивное обновление, что упрощает создание интерактивных
компонентов с минимальным количеством кода.
number или boolean для корректной
синхронизации с DOM.converter, чтобы корректно обрабатывать данные между
свойствами и атрибутами.Отражение атрибутов в FAST Element обеспечивает мощный, гибкий и безопасный способ управления состоянием компонентов через HTML, объединяя реактивность и контроль над DOM без лишнего кода. Это фундаментальная часть построения современных веб-компонентов с полной интеграцией в стандартные HTML-атрибуты.