Необязательные параметры

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

page('/user/:id?', function(ctx) {
    console.log(ctx.params.id);
});

В этом примере маршрут /user сработает и без параметра id, и с ним, например:

  • /userctx.params.id будет undefined
  • /user/123ctx.params.id будет "123"

Особенности использования:

  • Необязательный параметр всегда должен быть в конце маршрута.
  • Можно комбинировать несколько маршрутов, чтобы различать обработку с параметром и без него. Page.js не поддерживает несколько необязательных параметров подряд без явного указания.
page('/post/:category?/:id?', function(ctx) {
    console.log(ctx.params.category, ctx.params.id);
});

Здесь URL /post вернёт { category: undefined, id: undefined }, /post/tech{ category: "tech", id: undefined }, /post/tech/42{ category: "tech", id: "42" }.

Работа с контекстом ctx

Объект ctx содержит всю информацию о текущем маршруте. Для необязательных параметров важно проверять их наличие перед использованием:

page('/product/:id?', function(ctx) {
    if (ctx.params.id) {
        console.log('Загружаем продукт с ID:', ctx.params.id);
    } else {
        console.log('Отображаем список продуктов');
    }
});

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

Совмещение с query-параметрами

Page.js не парсит query-параметры (?key=value) автоматически, но можно получить их через window.location.search или сторонние библиотеки для парсинга.

page('/search/:term?', function(ctx) {
    const query = new URLSearchParams(window.location.search);
    const pageNum = query.get('page') || 1;
    console.log('Термин поиска:', ctx.params.term, 'Страница:', pageNum);
});

Необязательные параметры и query-параметры можно комбинировать для гибкой маршрутизации, например, фильтры или пагинация.

Использование необязательных параметров с middleware

Необязательные параметры отлично работают с middleware. Можно создавать промежуточные функции, которые проверяют наличие параметра и выполняют разные действия.

function loadUser(ctx, next) {
    if (ctx.params.id) {
        fetch(`/api/users/${ctx.params.id}`)
            .then(res => res.json())
            .then(user => {
                ctx.user = user;
                next();
            });
    } else {
        ctx.user = null;
        next();
    }
}

page('/user/:id?', loadUser, function(ctx) {
    if (ctx.user) {
        console.log('Пользователь загружен:', ctx.user.name);
    } else {
        console.log('Список пользователей');
    }
});

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

Комбинация необязательных и обязательных сегментов

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

// Правильно
page('/category/:cat?/item/:id', function(ctx) {
    console.log(ctx.params.cat, ctx.params.id);
});

// Неправильно
// page('/:cat?/item/:id', ...) — может работать нестабильно

Поддержка регулярных выражений и необязательных сегментов

Page.js позволяет использовать регулярные выражения в параметрах для более точного контроля. Это особенно полезно при необязательных параметрах:

page('/file/:name([a-z]+)?', function(ctx) {
    console.log('Имя файла:', ctx.params.name);
});

В этом случае маршрут сработает только если параметр соответствует регулярному выражению, или если он отсутствует.

Практические рекомендации

  • Всегда проверять ctx.params перед использованием необязательного параметра.
  • Для сложных маршрутов лучше разделять маршруты на несколько вызовов page(), чтобы избежать конфликтов.
  • Необязательные параметры удобны для пагинации, фильтров, вкладок и динамических страниц, где часть URL может отсутствовать.
  • Использовать middleware для обработки загрузки данных на основе наличия параметров, что делает код более модульным и читаемым.

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