Отправлять данные с одной страницы на другую вместо предварительной загрузки? - PullRequest
2 голосов
/ 13 февраля 2020

Допустим, у меня есть маршрут blog, который загружает полный массив всех сообщений в блоге. Отдельные сообщения в блоге живут на blog/[postId]. Есть ли у Sapper-idiomati c способ передачи данных для отдельной записи от blog до blog/[postId]?

По сути, если вы используете blog, я бы хотел предварительно загрузить код для отображения blog/[postId]. А затем, когда вы нажимаете ссылку на blog/[postId], мгновенно переходите туда и отображаете данные с blog. Но, конечно, если вы переходите непосредственно к blog/[postId], тогда все равно следует вызывать preload().

prefetch не совсем это делает, потому что для этого все еще требуется сетевой запрос. Я также попробовал предварительную загрузку, которая проверяет хранилище и не выдает сетевой запрос, если он не пустой, но вы не можете использовать хранилища в <script context="module">.

1 Ответ

1 голос
/ 15 февраля 2020

Спасибо @three за ваш комментарий , который привел меня к ответу.

Если маршрут или _layout компонент экспортирует preload(), он всегда вызывается при навигации. В итоге я сделал это, сохранив извлеченные данные во втором параметре в preload(), который обычно называется session и, по-видимому, используется всеми компонентами. И я звонил this.fetch(), только если данные еще не присутствовали.

<!-- blog/index.svelte -->
<script context="module">
  export async function preload (page, session) {
    let {posts} = session;
    if (undefined === posts) {
      const response = await this.fetch('blog/posts.json');
      posts = await response.json();
      session.posts = posts
    }

    return {posts}
  }
</script>

<script>
  export let posts;
</script>

{#each posts as post}
  <!-- ... -->
{/each}

Затем в [slug].svelte отметьте session.posts для сообщения, которое вы ищете, и если его нет, загрузить его.

<!-- blog/[slug].svelte -->
<script context="module">
  export async function preload (page, session) {
    const {slug} = page.params
    const {posts} = session
    let post

    if (undefined === posts) {
      const response = await this.fetch(`blog/${slug}.json`)
      post = await response.json()
    } else {
      post = posts.find(p => p.slug === slug)
    }

    if (undefined === post) {
      this.error(404, "Sorry we couldn\'t find that post")
    }

    return {post}
  }
</script>

<script>
  export let post
</script>

<!-- ... render post -->

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

Редактировать

На самом деле вам не нужно использовать сеансы как таковые , Если вы просто хотите, чтобы параметр session равнялся preload(page, session), а не был undefined, вы можете использовать его в server.js:

sapper.middleware({
  // Define session parameter as an empty object
  session: (req, res) => ({})
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...