简体   繁体   English

如何创建仅当新项目添加到另一个商店的数组时才执行代码的 Svelte 派生商店

[英]How to create a Svelte derived store that executes code only when new items are added to an array in another store

I'm working on a SvelteKit app in which all functionality is based on a list of URLs.我正在开发一个 SvelteKit 应用程序,其中所有功能都基于 URL 列表。 Users can add URLs to this list, or remove them.用户可以将 URL 添加到此列表,或将其删除。

When a new URL is added, the app fetches the URL and then runs multiple async operations on the fetched data.添加新的 URL 时,应用程序会获取 URL,然后对获取的数据运行多个异步操作。

I can think of many ways to build this, but I would like to use Svelte derived stores , if possible.我可以想出很多方法来构建它,但如果可能的话,我想使用 Svelte derived stores

  • The list of URLs would be stored in a writable store URL 列表将存储在可写存储
  • When a URL is added, a derived store runs all required async operations on this new URL (and not on the other URLs) and stores the results.添加 URL 后,派生存储会在此新的 URL(而不是其他 URL)上运行所有必需的异步操作并存储结果。

What's the most Svelte way to build this?构建它的最 Svelte 方法是什么?

The way I would do this is by using a custom store .我这样做的方法是使用自定义商店 createStores returns... createStores返回...

  • .urls A derived store of type string[] .urls类型为string[]的派生存储
  • .urlResults A readable store of type {url: string, value: unknown}[] .urlResults {url: string, value: unknown}[]类型的可读存储
  • .addUrl A function to add a URL .addUrl一个 function 添加一个 URL
  • .removeUrl A function to remove a URL. .removeUrl一个 function 删除一个 URL。

createStore takes a callback function of type (url: string, set: (v: unknown) => void) => void that is run whenever a new URL is added. createStore接受类型为(url: string, set: (v: unknown) => void) => void的回调 function 每当添加新的 URL 时运行。

import { writable, derived, get } from 'svelte/store';

function createStores(processUrl: (url: string, set: (v: unknown) => void) => void) {
    const urlResults = writable<{ url: string; value: unknown | null }[]>([]),
        urls = derived(urlResults, (all) => all.map((v) => v.url));

    const addUrl = (url: string) => {
        urlResults.update((v) => {
            v.push({ url, value: null });
            processUrl(url, (newValue) => {
                const index = get(urls).indexOf(url);
                if (index > -1) {
                    urlResults.update((current) => {
                        current[index].value = newValue;
                        return current;
                    });
                }
            });
            return v;
        });
    };

    const removeUrl = (url: string) => {
        urlResults.update((all) => all.filter((v) => v.url !== url));
    };

    return {
        urls,
        addUrl,
        removeUrl,
        urlResults: { subscribe: urls.subscribe }
    };
}

export default createStores((url, set) => {
    // Replace with your async actions
    setTimeout(() => set('Proccessed ' + url), 5000);
});
        

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM