Директива when

Директива when — одна из ключевых возможностей шаблонизации в FAST Element, предназначенная для условного отображения элементов DOM на основе логики в компоненте. Она позволяет управлять рендерингом фрагментов шаблона динамически, улучшая производительность и упрощая структуру кода.

Основы использования

when импортируется из пакета @microsoft/fast-element:

import { html, when } from '@microsoft/fast-element';

Синтаксис директивы выглядит следующим образом:

when(условие, () => html`<template>Контент</template>`)
  • условие — любое булево выражение или реактивное свойство компонента.
  • вторая функция — возвращает шаблон, который будет вставлен в DOM при истинности условия.

Пример:

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

class UserCard extends FASTElement {
    isLoggedIn = false;
}

const template = html<UserCard>`
    <div>
        ${when(x => x.isLoggedIn, html<UserCard>`<p>Добро пожаловать, пользователь!</p>`)}
        ${when(x => !x.isLoggedIn, html<UserCard>`<p>Пожалуйста, войдите в систему</p>`)}
    </div>
`;

FASTElement.define({
    name: 'user-card',
    template,
    styles: css`p { font-size: 16px; }`
});

В этом примере блок <p> с текстом отображается в зависимости от значения свойства isLoggedIn. Директива when автоматически отслеживает изменения свойства и обновляет DOM без необходимости вручную управлять элементами.

Обработка нескольких условий

Для множественных вариантов часто используют вложенные вызовы when или комбинацию с логическими операторами:

${when(x => x.status === 'loading', html`<p>Загрузка...</p>`)}
${when(x => x.status === 'success', html`<p>Данные загружены</p>`)}
${when(x => x.status === 'error', html`<p>Ошибка при загрузке</p>`)}

Такой подход позволяет избегать громоздких конструкций if-else и сохраняет реактивность шаблона.

Ленивая инициализация шаблонов

Функция, передаваемая в when, вызывается только тогда, когда условие истинно. Это снижает нагрузку на рендеринг и позволяет использовать тяжелые компоненты только по необходимости:

${when(
    x => x.showChart,
    () => html`<my-chart data="${x.chartData}"></my-chart>`
)}

Если showChart ложен, <my-chart> даже не создается, что экономит ресурсы браузера.

Удаление элементов при ложном условии

При переходе условия из true в false директива автоматически удаляет соответствующий фрагмент из DOM. Это отличается от скрытия через CSS, так как элемент полностью уничтожается и освобождает память. Такой механизм полезен для динамических списков, модальных окон и интерактивных панелей.

Интеграция с реактивными свойствами

when тесно работает с реактивной системой FAST Element. Любое свойство, помеченное как реактивное (@observable или объявленное через FASTElement), может быть использовано в условии. При изменении значения директива пересчитывает условие и обновляет DOM.

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

class ToggleButton extends FASTElement {
    @observable active = false;
}

const template = html<ToggleButton>`
    <button @click="${x => x.active = !x.active}">Переключить</button>
    ${when(x => x.active, html`<span>Включено</span>`)}
    ${when(x => !x.active, html`<span>Выключено</span>`)}
`;

Совместимость с другими директивами

when можно комбинировать с другими встроенными директивами FAST Element, такими как repeat или ref:

${when(x => x.items.length > 0, html`
    <ul>
        ${x => x.items.map(item => html`<li>${item}</li>`)}
    </ul>
`)}

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

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

  • Минимизация ререндеринга: шаблон создается только при необходимости.
  • Удаление неиспользуемого DOM: элементы, которых нет по условию, не занимают память.
  • Поддержка реактивных выражений: любые изменения свойств автоматически отражаются в DOM.

Директива when является легковесным и мощным инструментом для управления условным отображением элементов, интегрированным в реактивную модель FAST Element. Ее использование упрощает код, повышает производительность и делает шаблоны более декларативными.