Как мне структурировать маршрут Sapper/Svelte, когда данные загружаются из S3?

Допустим, у меня есть несколько документов с данными, которые являются документами JSON в S3, по одному в год. У меня есть маршрут, определенный в Sapper через структуру dir:

├── routes
│   ├── _error.svelte
│   ├── _layout.svelte
│   ├── about.svelte
│   ├── data
│   │   ├── [year].svelte

И код в моем script блок:

  let yearData;
  onMount(async () => {
    const f = await fetch(yearDataUrl(year), {
      headers: { 'Access-Control-Allow-Origin': '*' }
    });
    const jsonResults = await f.json();
    yearData = jsonResults;
  });

Каждый набор данных в S3 как [s3 url]/[year here].json, В навигационной панели есть набор ссылок, которые показывают каждый набор данных. Я могу получить данные для загрузки в onMount хорошо, но последующие клики по ссылкам панели навигации не загружают новые данные. Так onMount Вероятно, это неправильный выбор.

Как мне это структурировать? Также стоит отметить, что я хотел бы представить эти страницы в виде статических файлов в будущем (данные меняются редко, особенно за предыдущие годы).

1 ответ

Есть два варианта. Первый и самый идиоматичный - и правильный, в вашей ситуации, поскольку кажется, что вы хотите использовать рендеринг на стороне сервера - это использование предварительной загрузки:

<script context="module">
  export async function preload(page) {
    const f = await this.fetch(yearDataUrl(page.params.year), {
      headers: { 'Access-Control-Allow-Origin': '*' }
    });

    return {
      yearData: await f.json()
    };
  }
</script>

<script>
  export let yearData;
</script>

<!-- use yearData here -->

Функция предварительной загрузки будет запущена до создания компонента, предоставляя ему yearData двигательный Когда бы ни page.params изменения, preload будет работать снова, установив новую опору.

Потому что это работает на сервере, а также на клиенте (следовательно, использование this.fetch скорее, чем fetch(который работает в обеих средах), вы получите страницы, отображаемые на сервере, а не сообщение о загрузке, которое переходит на страницу, как только onMount пробеги.

Второй вариант, включенный для полноты картины, заключается в использовании хранилища страниц:

<script>
  import { stores } from '@sapper/app';

  const { page } = stores();

  let yearData;

  $: if (process.browser) {
      fetch(yearDataUrl(page.params.year))
        .then(f => f.json())
        .then(data => {
          yearData = data;
        });
  }
</script>

В этом случае yearData не будет отображаться на сервере. (Чтобы быть полным, вам также необходимо обрабатывать условия гонки и ошибки, которые не являются проблемой с preload.)

Другие вопросы по тегам