Свойство ctx.query

В библиотеке Page.js объект ctx (контекст) является ключевым элементом маршрутизации. Он содержит всю информацию о текущем переходе, включая путь, параметры, состояние и другие данные. Одним из важнейших свойств ctx является ctx.query, которое предназначено для работы с строкой запроса URL — частью адреса, начинающейся с ?.


Формат и структура ctx.query

Свойство ctx.query представляет собой объект JavaScript, где каждое имя параметра запроса становится ключом, а значение параметра — соответствующим значением. Например, для URL:

/search?term=pagejs&sort=asc

ctx.query будет выглядеть так:

{
  term: "pagejs",
  sort: "asc"
}

Если параметр встречается несколько раз, Page.js сохраняет последнее значение, игнорируя предыдущие.


Получение данных из строки запроса

Доступ к параметрам осуществляется напрямую через объект ctx.query:

page('/search', (ctx) => {
  console.log(ctx.query.term); // "pagejs"
  console.log(ctx.query.sort); // "asc"
});

В данном примере:

  • ctx.query.term — значение параметра term.
  • ctx.query.sort — значение параметра sort.

Это упрощает обработку фильтров, поисковых запросов, сортировок и других данных, передаваемых через URL.


Динамическая маршрутизация с использованием query

Page.js позволяет комбинировать параметры пути и query-параметры:

page('/products/:id', (ctx) => {
  console.log(ctx.params.id); // параметр пути, например "123"
  console.log(ctx.query.ref); // query-параметр, например "homepage"
});

URL:

/products/123?ref=homepage

Результат:

ctx.params.id === "123"
ctx.query.ref === "homepage"

Таким образом, ctx.query удобно использовать для передачи дополнительной информации без изменения основной структуры маршрута.


Преобразование query-параметров

По умолчанию, все значения в ctx.query строкового типа. Для числовых или логических значений требуется явное преобразование:

page('/items', (ctx) => {
  const limit = parseInt(ctx.query.limit, 10) || 10;
  const active = ctx.query.active === 'true';
  console.log(limit, active);
});

URL:

/items?limit=20&active=true

Результат:

limit === 20
active === true

Обработка отсутствующих query-параметров

Если параметр отсутствует в URL, его ключ не создаётся в ctx.query. Для безопасной работы рекомендуется использовать проверку или значения по умолчанию:

page('/search', (ctx) => {
  const term = ctx.query.term || '';
  const pageNum = parseInt(ctx.query.page, 10) || 1;
  console.log(term, pageNum);
});

URL:

/search

Результат:

term === ""
pageNum === 1

Работа с несколькими query-параметрами

Для URL с множеством параметров Page.js автоматически формирует объект:

/filter?category=books&price_min=100&price_max=500
page('/filter', (ctx) => {
  const { category, price_min, price_max } = ctx.query;
  console.log(category, price_min, price_max);
});

Результат:

category === "books"
price_min === "100"
price_max === "500"

Для удобства можно преобразовать их в числа или другие типы, используя методы JavaScript.


Ограничения и особенности

  1. Отсутствие автоматического парсинга массивов Стандартный ctx.query не распознаёт параметры вида tags[]=a&tags[]=b. В таких случаях требуется дополнительная обработка:
const tags = (ctx.query.tags || "").split(',');
  1. Все значения строковые Любые числа, булевы значения или даты необходимо преобразовывать вручную.

  2. Параметры с одинаковым именем Page.js сохраняет последнее значение, что важно учитывать при передаче нескольких значений через один ключ.


Использование с программной навигацией

Query-параметры можно передавать при вызове page() для перехода:

page('/search?term=pagejs&sort=asc');

После этого в обработчике маршрута:

page('/search', (ctx) => {
  console.log(ctx.query.term); // "pagejs"
  console.log(ctx.query.sort); // "asc"
});

Это удобно для обновления состояния приложения без перезагрузки страницы.


Практические примеры

  1. Фильтрация списка продуктов по цене и категории
page('/products', (ctx) => {
  const category = ctx.query.category || 'all';
  const minPrice = parseFloat(ctx.query.min) || 0;
  const maxPrice = parseFloat(ctx.query.max) || Infinity;

  const filtered = products.filter(p => 
    (category === 'all' || p.category === category) &&
    p.price >= minPrice && p.price <= maxPrice
  );

  renderProducts(filtered);
});
  1. Сортировка элементов по полю
page('/items', (ctx) => {
  const sortField = ctx.query.sortBy || 'name';
  const direction = ctx.query.order === 'desc' ? -1 : 1;

  items.sort((a, b) => (a[sortField] > b[sortField] ? direction : -direction));
});
  1. Постраничная навигация
page('/blog', (ctx) => {
  const pageNumber = parseInt(ctx.query.page, 10) || 1;
  const pageSize = 10;
  const start = (pageNumber - 1) * pageSize;
  const paginatedPosts = posts.slice(start, start + pageSize);

  renderPosts(paginatedPosts);
});

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