Шаблоны высшего порядка

FAST Element — это библиотека для создания Web Components с высокой производительностью и удобной системой реактивности. Одним из продвинутых инструментов в FAST является концепция шаблонов высшего порядка (Higher-Order Templates, HOT). Эти шаблоны позволяют создавать повторно используемые структуры и композиции компонентов с динамическими данными, минимизируя дублирование кода.


Основы шаблонов высшего порядка

Шаблон высшего порядка — это функция, которая возвращает другой шаблон FAST. В FAST шаблоны создаются с помощью функции html из пакета @microsoft/fast-element. Простейший пример шаблона:

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

const baseTemplate = html`<div>${x => x.content}</div>`;

Шаблон высшего порядка добавляет возможность параметризации шаблона функцией:

function withBorder(color) {
    return html`<div style="border: 2px solid ${color}; padding: 10px;">
        <slot></slot>
    </div>`;
}

const redBox = withBorder("red");
const blueBox = withBorder("blue");

Здесь withBorder — это HOT: она возвращает готовый шаблон, где внутреннее оформление зависит от переданного параметра.

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


Параметризация и композиция

Шаблоны высшего порядка позволяют создавать композиции шаблонов. Например, можно комбинировать базовый шаблон с дополнительными модификациями:

function cardTemplate(title, contentTemplate) {
    return html`
        <div class="card">
            <h3>${title}</h3>
            ${contentTemplate}
        </div>
    `;
}

const userCard = cardTemplate("Пользователь", html`<p>${x => x.userName}</p>`);

Такой подход делает структуру компонентов гибкой: один и тот же базовый шаблон может быть использован в разных контекстах с разным содержимым.


HOT и реактивность FAST

FAST поддерживает реактивные свойства через классы элементов. Шаблон высшего порядка может принимать функции, вычисляющие содержимое на основе состояния компонента:

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

const toggleTemplate = state => html`
    <button @click="${() => state.active = !state.active}">
        ${() => state.active ? "Включено" : "Выключено"}
    </button>
`;

class ToggleElement extends FASTElement {
    active = false;
}

FASTElement.define({
    name: "toggle-element",
    template: toggleTemplate(this),
    styles: css`button { padding: 5px 10px; }`
});

В этом примере шаблон реагирует на изменения свойства active, обеспечивая динамическое обновление интерфейса.


Переиспользование стилей через HOT

Шаблоны высшего порядка удобно комбинировать с CSS:

function styledBox(styleObj) {
    return html`
        <div style="${() => Object.entries(styleObj).map(([k,v]) => `${k}:${v}`).join(';')}">
            <slot></slot>
        </div>
    `;
}

const greenBox = styledBox({ background: "green", padding: "20px" });

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

  • Стили формируются динамически из объекта JavaScript.
  • Один и тот же шаблон можно использовать с разными стилями без дублирования CSS.

HOT для вложенных компонентов

Шаблоны высшего порядка упрощают создание вложенных компонентов с параметрами:

function listTemplate(items, itemTemplate) {
    return html`
        <ul>
            ${items.map(item => html`<li>${itemTemplate(item)}</li>`)}
        </ul>
    `;
}

const userList = listTemplate(
    [{name: "Аня"}, {name: "Борис"}],
    user => html`<strong>${user.name}</strong>`
);

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


Производительность и мемоизация HOT

Шаблоны высшего порядка могут быть мемоизированы, чтобы не пересоздавать шаблон каждый раз при рендере:

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

const memoizedTemplate = (() => {
    const cache = new Map();
    return function(color) {
        if (!cache.has(color)) {
            cache.set(color, html`<div style="color:${color}"><slot></slot></div>`);
        }
        return cache.get(color);
    }
})();

Преимущество: при многократном использовании одного и того же параметра шаблон берется из кеша, что снижает накладные расходы на рендеринг.


Сценарии использования HOT

  1. Тематические обертки — разные визуальные темы (темная/светлая, цветовые схемы) без дублирования HTML.
  2. Универсальные карточки и списки — одна структура для разных типов данных.
  3. Динамическая композиция — вставка разных дочерних шаблонов в общий контейнер.
  4. Реактивные элементы с параметрами — шаблоны, которые изменяются в зависимости от состояния компонента.

Шаблоны высшего порядка в FAST Element открывают возможности модульного, динамического и эффективного построения интерфейсов, сочетая гибкость реактивности с повторным использованием шаблонов. Их применение позволяет поддерживать чистую архитектуру компонентов и минимизировать дублирование кода при создании сложных UI.