В FAST Element пользовательские директивы представляют собой механизм расширения шаблонов и управления поведением DOM без необходимости вмешательства в жизненный цикл компонентов напрямую. Директива позволяет инкапсулировать повторяемую логику привязки и реактивного обновления, обеспечивая более чистый и выразительный код.
Директива в FAST Element — это функция, возвращающая объект с
методами жизненного цикла: bind, update и
unbind. Она применяется внутри шаблона с помощью синтаксиса
${directive()}.
Типичная директива состоит из нескольких ключевых частей:
Функция директивы Создает замыкание для хранения состояния и конфигурации.
Метод bind Вызывается при первом
связывании с DOM. Используется для инициализации элементов и установки
первоначальных значений.
Метод update Отвечает за обновление
состояния при изменении данных. Позволяет изменять DOM без полной
перерисовки.
Метод unbind Очищает ресурсы,
удаляет слушатели и отменяет побочные эффекты при удалении элемента из
DOM.
Пример минимальной структуры:
import { directive, NodePart } from '@microsoft/fast-element';
export const myDirective = directive((value) => {
return {
bind(part) {
if (part instanceof NodePart) {
part.setValue(`Initial: ${value}`);
}
},
update(part, [value]) {
if (part instanceof NodePart) {
part.setValue(`Updated: ${value}`);
}
},
unbind(part) {
// очистка ресурсов
}
};
});
Директива подключается в шаблоне компонента следующим образом:
import { html, FASTElement } from '@microsoft/fast-element';
import { myDirective } from './directives/myDirective.js';
const template = html<MyComponent>`
<div>${x => myDirective(x.someValue)}</div>
`;
class MyComponent extends FASTElement {
someValue = 'Тест';
}
Ключевой момент: директива работает на уровне частей
шаблона (NodePart, AttributePart,
BooleanAttributePart) и автоматически обновляется при
изменении привязанных данных.
Пользовательские директивы позволяют управлять не только содержимым узлов, но и атрибутами, стилями и событиями. Для этого используется проверка типа части:
bind(part) {
if (part.type === 'attribute') {
part.setValue(`color: ${this.value}`);
} else if (part.type === 'node') {
part.setValue(this.value);
}
}
Для добавления обработчиков событий:
update(part, [handler]) {
if (part instanceof NodePart) {
const node = part.start.parentNode;
node.removeEventListener('click', part.oldHandler);
node.addEventListener('click', handler);
part.oldHandler = handler;
}
}
Директива может принимать любые аргументы, включая массивы, объекты и
функции. Для обеспечения реактивности важно использовать методы
update и хранить предыдущее состояние внутри замыкания:
export const reactiveDirective = directive((value) => {
let previousValue;
return {
update(part) {
if (previousValue !== value) {
part.setValue(`Value changed to: ${value}`);
previousValue = value;
}
}
};
});
Таким образом, перерисовка происходит только при реальном изменении данных, что повышает производительность.
Директивы могут быть вложенными и комбинироваться для создания
сложных реактивных шаблонов. Например, директива может использовать
другую директиву внутри update:
export const compositeDirective = directive((value) => {
const inner = anotherDirective(value);
return {
bind(part) {
inner.bind(part);
},
update(part, [value]) {
inner.update(part, [value]);
}
};
});
Это позволяет строить модульные и повторно используемые решения без дублирования кода.
update.bind и unbind.Пользовательские директивы в FAST Element предоставляют мощный инструмент для управления DOM и реактивностью, позволяя создавать высокопроизводительные, читаемые и модульные компоненты.