如何将额外参数从`page.svelte`传递到相同路由中的`page.js`,在Sveltekit中。

huangapple go评论59阅读模式
英文:

How to send extra parameters from page.svelte to page.js inside the same route in Sveltekit

问题

我正在尝试理解SvelteKit的工作原理。在我的SvelteKit演示应用程序中,我在同一个路由下有+page.svelte+page.js文件。

+page.js从API获取数据,然后将数据发送给+page.svelte。但这是单向通信。如果我想要向+page.js发送一些参数,比如我想在页面上显示多少个项目,该怎么办?

我注意到params只包含slug。而且我不想使用类似/products?limit=10&skip=0的URL查询参数。

page.js

import { Store } from '@models';

/** @type {import('./$types').PageServerLoad} */
export async function load({params}) {
    // 类似这样的内容:
    let limit = params.limit || 10
    let skip = params.skip || 0
    let res = await Store.get(limit, skip)
    return {
        store: res
    };
};

page.svelte

export let data
let products = data.store

const loadMore = () => {
    // 接下来该怎么做?
}
{#each products as product}
    {product.title}
{/each}
<button on:click={loadMore}>加载更多</button>

有办法实现这个吗?还是我漏掉了什么?

英文:

I am trying to understand how sveltekit works. Inside my sveltekit demo app, I have +page.svelte and +page.js files at the same route.

+page.js, which gets data from the API, sends data to +page.svelte. But it is a one way communication. What if I want to send some parameters to +page.js; sth like how many items that I want to show on my page.

I see that params only contains slug. And I don't want to use url queries like /products?limit=10&amp;skip=0

page.js

import { Store } from &#39;@models&#39;

/** @type {import(&#39;./$types&#39;).PageServerLoad} */
export async function load({params}) {
    // Sth like this:
    let limit = params.limit || 10
    let skip = params.skip || 0
    let res = await Store.get(limit,skip)
    return {
        store: res
    };
};

page.svelte

export let data
let products = data.store

const loadMore = () =&gt; {
    // What to do next???
}
{#each products as product}
    {product.title}
{/each}
&lt;button on:click={loadMore}&gt;Load More&lt;/button&gt;

Is there a way to achieve this? Or am I missing something?

答案1

得分: 1

请参阅高级路由文档

如果您不想使用查询,唯一的替代方法是使用可选参数,因此您可能应该将您的路由文件移动到类似以下的位置:

src/routes/products/[[skip]]/[[limit]]/+page.svelte

这将允许路由在末尾具有这两个参数,但它们不是必需的。因此,以下所有路由都是有效的:

/products
/products/1
/products/1/10

未提供的参数将不会出现在params对象中。所有参数值都是字符串。

加载更多项目只是使用goto进行导航的问题,例如:

import { goto } from '$app/navigation';
import { page } from '$app/stores';

$: skip = +($page.params.skip ?? 0);
$: limit = +($page.params.limit ?? 10);

const loadMore = () => {
    goto(`/products/${skip + limit}/${limit}`);
}
英文:

See the advanced routing documentation.

If you do not want to use a query the only alternative is using optional parameters, so you probably should move your route files to something like:

src/routes/products/[[skip]]/[[limit]]/+page.svelte

This will allow the route to have those two parameters at the end, but they are not required. So all of these routes are valid:

/products
/products/1
/products/1/10

Parameters that are not provided will not appear in the params object. All param values are strings.

Load more items would just be a matter of navigating using goto, e.g.

import { goto } from &#39;$app/navigation&#39;;
import { page } from &#39;$app/stores&#39;;

$: skip = +($page.params.skip ?? 0);
$: limit = +($page.params.limit ?? 10);

const loadMore = () =&gt; {
    goto(`/products/${skip + limit}/${limit}`);
}

答案2

得分: 1

I found a new way of achieving what I really wanted. It still does not seem to be the best solution, but it is the most efficient way for my case right now.

I used the built-in depends() function with invalidate as described here. This way I can update the data object for my needs.

So the final code is like below

page.svelte

    const loadMore = () => {
        data.loadMore(2)
    }
    const reset = () => {
        data.reset()
    }

page.js

import { Store } from '@models';
import { invalidate } from '$app/navigation';
let count = 1;

export async function load({ depends }) {
    let res = await Store.get(count);
    depends('update');
    return {
        store: res,
        count: count,
        loadMore: (e) => {
            invalidate('update');
            count += e;
        },
        reset: () => {
            invalidate('update');
            count = 1;
        }
    };
}

Important

I did not have much time to test this. So please read the documentation carefully before using.
I would appreciate any comments for this approach.

英文:

I found a new way of achieving what I really wanted. It still does not seem to be the best solution, but it is the most efficient way for my case right now.

I used the built-in depends() function with invaidate as described here. This way I can update the data object for my needs.

So the final code is like below

page.svelte

    const loadMore = () =&gt; {
        data.loadMore(2)
    }
    const reset = () =&gt; {
        data.reset()
    }

page.js

import { Store } from &#39;@models&#39;
import { invalidate } from &#39;$app/navigation&#39;;
let count = 1
/** @type {import(&#39;./$types&#39;).PageServerLoad} */

export async function load({depends}) {
    let res = await Store.get(count)
    depends(&#39;update&#39;);
    return {
        store: res,
        count: count,
        loadMore: (e) =&gt; {
            invalidate(&#39;update&#39;);
            count+= e
        },
        reset: () =&gt; {
            invalidate(&#39;update&#39;);
            count = 1
        }
    };
}

> ## Important ##
> I did not have much time to test this. So please read the documentation carefully before using.
> I would appreciate any comments for this approach.

huangapple
  • 本文由 发表于 2023年2月9日 00:03:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75388518.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定