英文:
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&skip=0
page.js
import { Store } from '@models'
/** @type {import('./$types').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 = () => {
    // What to do next???
}
{#each products as product}
    {product.title}
{/each}
<button on:click={loadMore}>Load More</button>
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 '$app/navigation';
import { page } from '$app/stores';
$: skip = +($page.params.skip ?? 0);
$: limit = +($page.params.limit ?? 10);
const loadMore = () => {
    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 = () => {
        data.loadMore(2)
    }
    const reset = () => {
        data.reset()
    }
page.js
import { Store } from '@models'
import { invalidate } from '$app/navigation';
let count = 1
/** @type {import('./$types').PageServerLoad} */
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论