Программная навигация

Marko — это высокопроизводительный фреймворк для создания веб-приложений на JavaScript, который позволяет эффективно управлять рендерингом и взаимодействием с клиентом. Одной из ключевых возможностей Marko является поддержка программной навигации, что позволяет динамически изменять маршруты и обрабатывать переходы без перезагрузки страницы. Это важный аспект для создания современных одностраничных приложений (SPA).

Что такое программная навигация?

Программная навигация — это процесс изменения состояния маршрутов в приложении через JavaScript, без необходимости перезагрузки страницы. В Marko она интегрируется с клиентской логикой с использованием API, которые позволяют изменять URL, вызывать переходы и динамически изменять содержимое, не вызывая полную перезагрузку страницы.

Для создания программной навигации в Marko можно использовать две основные концепции:

  1. Роутинг — определение того, какой компонент или страницу отобразить на основе текущего URL.
  2. Навигация — управление переходами между различными частями приложения, чтобы обеспечить гибкость в пользовательском интерфейсе.

Роутинг и маршруты в Marko

В Marko для управления маршрутизацией чаще всего используется библиотека, такая как Marko Router, которая служит для обработки входящих запросов и рендеринга соответствующих компонентов. Роутинг позволяет связывать URL с определёнными компонентами или страницами.

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

const marko = require("marko");
const express = require("express");
const app = express();

const homeTemplate = marko.load(require.resolve("./home.marko"));
const aboutTemplate = marko.load(require.resolve("./about.marko"));

app.get("/", (req, res) => {
  homeTemplate.render({}, res);
});

app.get("/about", (req, res) => {
  aboutTemplate.render({}, res);
});

В этом примере определены два маршрута: / и /about, каждый из которых рендерит определённый компонент. Однако этот подход работает на стороне сервера, и при изменении маршрута происходит полная перезагрузка страницы. Для программной навигации в Marko используется другая техника.

Программная навигация с помощью API

В Marko программная навигация достигается с использованием JavaScript API для работы с маршрутом без необходимости перезагрузки страницы. Стандартный API, используемый для этой цели, — это history API.

Marko предоставляет возможность обработки переходов с использованием методов, таких как history.pushState(), history.replaceState() и слушателей событий.

  1. pushState — изменяет текущий URL, добавляя новый элемент в историю браузера. Этот метод используется для навигации между страницами.

    Пример:

    window.history.pushState({}, "", "/new-page");
  2. replaceState — изменяет текущий URL, но не добавляет новый элемент в историю браузера. Это полезно для обновления URL без изменения истории.

    Пример:

    window.history.replaceState({}, "", "/updated-page");
  3. popstate — событие, которое срабатывает, когда пользователь возвращается или переходит на предыдущие страницы с помощью кнопок “Назад” или “Вперед”. Это позволяет синхронизировать состояние страницы с изменениями URL.

    Пример:

    window.addEventListener("popstate", (event) => {
      console.log("Произошел переход в состояние", event.state);
    });

С использованием этих методов можно динамически изменять URL и отображать компоненты, соответствующие новому состоянию, без перезагрузки страницы. Однако сам по себе Marko не управляет состоянием URL — для этого обычно добавляется небольшая клиентская логика.

Навигация в контексте компонентов

Для реализации переходов между компонентами в Marko можно использовать встроенные механизмы управления состоянием и событиями. Например, компонент может реагировать на изменение URL и перерисовывать своё состояние в зависимости от нового маршрута.

Пример компонента, который меняет своё содержимое при изменении URL:

class Page {
  onCreate() {
    this.state = {
      currentPage: window.location.pathname
    };
  }

  onUpdate() {
    this.state.currentPage = window.location.pathname;
  }

  render() {
    if (this.state.currentPage === "/about") {
      return "О нас";
    } else {
      return "Главная страница";
    }
  }
}

Этот компонент отслеживает текущий URL с помощью window.location.pathname и обновляет отображаемое содержимое, когда путь изменяется.

Использование сторонних библиотек для навигации

Хотя Marko предоставляет базовые возможности для программной навигации, в реальных приложениях часто используются дополнительные библиотеки, такие как Page.js, React Router (с интеграцией в Marko), которые упрощают процесс работы с маршрутами и обеспечивают дополнительные возможности.

Например, библиотека Page.js может использоваться для более удобного управления маршрутами. Пример использования Page.js в Marko:

const page = require("page");

page("/", () => {
  // рендер компонента для главной страницы
});
page("/about", () => {
  // рендер компонента для страницы "О нас"
});

page();

В данном случае Page.js автоматически отслеживает изменения URL и вызывает соответствующие обработчики, что упрощает реализацию навигации.

Взаимодействие с серверной частью

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

Для динамической загрузки данных можно использовать Marko’s streaming API, который позволяет передавать данные с сервера на клиент. Например, при переходе на страницу, которая требует загрузки данных, можно отправить запрос на сервер, получить данные и обновить компонент на клиенте.

Пример загрузки данных при программной навигации:

// Клиентская часть
window.addEventListener("popstate", () => {
  loadData(window.location.pathname);
});

function loadData(path) {
  fetch(`/api/data${path}`)
    .then(response => response.json())
    .then(data => {
      // обновить компонент с полученными данными
    });
}

Заключение

Программная навигация в Marko позволяет создавать динамичные и быстрые веб-приложения без необходимости перезагрузки страницы. С помощью API истории и интеграции с компонентами Marko можно легко управлять маршрутами и состоянием приложения. Комбинирование этих возможностей с серверным рендерингом и использованием сторонних библиотек позволяет создавать гибкие и масштабируемые решения для современных веб-приложений.