HTTP-запросы

FAST Element — современная библиотека для создания веб-компонентов на JavaScript с поддержкой реактивного рендеринга и декларативного синтаксиса. Часто при разработке компонентов требуется взаимодействие с внешними API через HTTP-запросы. В FAST Element это реализуется через стандартные веб-технологии, такие как fetch, с добавлением реактивной привязки данных и методов жизненного цикла компонентов.


Использование fetch внутри компонентов

Базовый способ выполнения HTTP-запроса — использование встроенного метода fetch. В FAST Element запросы обычно выполняются в методе жизненного цикла connectedCallback, который вызывается после добавления компонента в DOM:

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

const template = html`
  

Данные:

    ${x => x.items.map(item => html`
  • ${item.name}
  • `)}
`; const styles = css` h2 { color: #333; } `; export class MyComponent extends FASTElement { items = []; connectedCallback() { super.connectedCallback(); this.loadData(); } async loadData() { try { const response = await fetch("https://api.example.com/items"); if (!response.ok) throw new Error("Ошибка загрузки данных"); const data = await response.json(); this.items = data; } catch (error) { console.error(error); } } } FASTElement.define({ name: "my-component", template, styles, ElementClass: MyComponent });

Ключевые моменты:

  • connectedCallback позволяет выполнять действия сразу после добавления компонента в DOM.
  • Привязка items в шаблоне автоматически обновляет DOM при изменении данных.
  • Обработка ошибок необходима для предотвращения сбоев при сетевых ошибках.

Реактивные свойства и обновление данных

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

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

export class ReactiveComponent extends FASTElement {
  @observable data = [];

  async fetchData() {
    const response = await fetch("/api/data");
    this.data = await response.json();
  }
}

const template = html`
  
    ${x => x.data.map(item => html`
  • ${item.title}
  • `)}
`;

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

  • Объявление свойства через @observable делает его реактивным.
  • Прямое присваивание this.data = ... вызывает повторный рендер шаблона.
  • Реактивные свойства можно использовать для динамического состояния, таких как загрузка данных, ошибки или фильтры.

Управление состоянием загрузки и ошибок

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

export class FetchStateComponent extends FASTElement {
  @observable items = [];
  @observable isLoading = false;
  @observable error = null;

  async loadItems() {
    this.isLoading = true;
    this.error = null;

    try {
      const response = await fetch("/api/items");
      if (!response.ok) throw new Error("Ошибка сервера");
      this.items = await response.json();
    } catch (err) {
      this.error = err.message;
    } finally {
      this.isLoading = false;
    }
  }
}

const template = html`
  
${x => x.isLoading ? html`

Загрузка...

` : ""} ${x => x.error ? html`

${x.error}

` : ""}
    ${x => x.items.map(item => html`
  • ${item.name}
  • `)}
`;

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

  • isLoading управляет отображением индикатора загрузки.
  • error используется для вывода сообщений о проблемах с сетью.
  • Привязка в шаблоне позволяет динамически менять DOM без ручного вмешательства.

Выполнение POST-запросов и отправка данных

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

async sendData(payload) {
  try {
    const response = await fetch("/api/items", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload)
    });
    if (!response.ok) throw new Error("Ошибка при отправке данных");
    const result = await response.json();
    this.items.push(result);
  } catch (error) {
    console.error(error);
  }
}

Особенности POST-запросов:

  • Метод POST позволяет отправлять объект в формате JSON.
  • Заголовок Content-Type необходим для корректной обработки сервером.
  • Результат запроса можно сразу добавить в реактивное свойство, чтобы обновить интерфейс.

Интеграция с формами и событиями

FAST Element поддерживает работу с событиями DOM. Это позволяет выполнять HTTP-запросы по действиям пользователя, например, при отправке формы:

const template = html`
  
x.handleSubmit(event)}>
`; handleSubmit(event) { event.preventDefault(); const formData = new FormData(event.target); const payload = { name: formData.get("name") }; this.sendData(payload); }

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

  • @submit привязывает метод класса к событию формы.
  • event.preventDefault() предотвращает стандартное поведение браузера.
  • FormData упрощает сбор данных из формы и передачу их на сервер.

Асинхронная реактивность и ререндер

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

async refreshData() {
  const newItems = await fetch("/api/items").then(r => r.json());
  this.items = newItems;
}

Принцип: реактивные свойства + асинхронные операции = минимальный код для динамического UI.


Советы по организации HTTP-запросов в FAST Element

  1. Вынесение запросов в отдельные методы класса делает код более читаемым и поддерживаемым.
  2. Использование реактивных свойств для хранения состояния упрощает управление UI.
  3. Обработка ошибок и индикаторы загрузки повышают стабильность компонентов.
  4. Асинхронные функции можно вызывать в connectedCallback, событиях или реактивных наблюдателях (@watch).
  5. Для сложных проектов рекомендуется создавать отдельные сервисы для взаимодействия с API и вызывать их из компонентов.