Директивы

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


Основы директив

Директива — это функция или объект с методом render, который возвращает результат вычисления. В шаблоне FAST Element директива вызывается внутри фигурных скобок {}, аналогично выражениям. Простейший пример:

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

class MyList extends FASTElement {
  items = ["Apple", "Banana", "Cherry"];
}

const template = html<MyList>`
  <ul>
    ${repeat(x => x.items, html<string>`<li>${x}</li>`)}
  </ul>
`;

Здесь repeat — встроенная директива, которая повторяет шаблон для каждого элемента массива. Важно понимать, что директива не возвращает конечный DOM напрямую, она управляет виртуальным выражением и обновлениями.


Типы встроенных директив

FAST Element включает несколько ключевых директив:

  1. repeat — повторение шаблонов для массивов или коллекций.

    • Аргументы:

      • Функция для получения коллекции.
      • Шаблон для каждого элемента.
    • Поддерживает ключи для оптимального обновления DOM.

    ${repeat(
      x => x.items,
      html<string>`<li>${x}</li>`,
      { key: x => x.id }
    )}
  2. when — условное отображение контента.

    • Аргументы:

      • Условие (функция, возвращающая boolean).
      • Шаблон для true.
      • Опционально: шаблон для false.
    ${when(
      x => x.isLoggedIn,
      html<MyList>`<p>Добро пожаловать!</p>`,
      html<MyList>`<p>Пожалуйста, войдите.</p>`
    )}
  3. guard — предотвращает ненужные перерисовки, когда данные не изменились.

    • Часто используется с массивами или объектами, чтобы сократить работу с DOM.
    ${guard(
      x => x.items,
      html<MyList>`${repeat(x => x.items, html<string>`<li>${x}</li>`)}`
    )}
  4. html и unsafeHTML — вставка динамического HTML.

    • html безопасно обрабатывает шаблонные строки.
    • unsafeHTML вставляет строку как HTML напрямую (опасно с точки зрения XSS).
    import { unsafeHTML } from "@microsoft/fast-element";
    const template = html<MyList>`<div>${x => unsafeHTML(x.htmlString)}</div>`;

Создание собственных директив

Собственная директива — это функция, возвращающая объект с методом render. Основной контракт:

function myDirective(arg) {
  return {
    render(source) {
      return `${source} - processed ${arg}`;
    }
  };
}

Применение в шаблоне:

const template = html<MyList>`<p>${myDirective("test")}</p>`;

Для более сложных случаев директива может иметь метод update, который вызывается при изменении данных без пересоздания DOM:

function highlightDirective(color) {
  return {
    render(content) {
      return html`<span style="background-color:${color}">${content}</span>`;
    },
    update(part, value) {
      part.setValue(html`<span style="background-color:${color}">${value}</span>`);
    }
  };
}

Метод update позволяет избежать полной перерисовки узла и управлять только частью DOM.


Директивы и реактивность

Директивы работают в связке с реактивной системой FAST Element. Любое выражение в шаблоне, обернутое в директиву, автоматически подписывается на изменения свойств компонента. Это значит:

  • Изменение свойства вызывает update директивы.
  • Директива может управлять атрибутами, текстом и вложенными элементами.
  • Использование guard и repeat позволяет контролировать производительность при работе с большими коллекциями.

Пример комбинирования директив:

${when(
  x => x.items.length > 0,
  html<MyList>`
    <ul>
      ${repeat(x => x.items, html<string>`<li>${x}</li>`)}
    </ul>
  `,
  html<MyList>`<p>Список пуст</p>`
)}

В этом примере:

  • when проверяет условие.
  • repeat генерирует элементы списка только если есть данные.
  • Обновления происходят автоматически при изменении массива items.

Советы по использованию

  • Для динамических массивов всегда использовать repeat с ключами для эффективного обновления DOM.
  • guard полезен, когда входные данные изменяются редко, но пересоздание шаблона дорого.
  • Директивы можно комбинировать, создавая сложные условия отображения.
  • При работе с HTML-строками использовать unsafeHTML только для доверенного контента.
  • Собственные директивы лучше строить с поддержкой методов render и update, чтобы минимизировать манипуляции с DOM.

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