Обновление маршрута при нажатии кнопки повторной навигации в навигаторе в Сапере

#svelte #sapper #svelte-3

#стройный #сапер #стройный-3

Вопрос:

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

В настоящее время я работаю с onMount, но пробовал BeforeUpdate и AfterUpdate. Я также пытался просто включить это в скрипт как функции, но это не обновляется.

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

Вот код для панели поиска, с помощью которого я пытался replaceState: True , но, похоже, это ничего не дало.

 async function sendSearchTerms(terms) {
    await goto("recipe", { replaceState: true });
    searchItems.set(terms);
}
  

Вот код в маршруте, на который он перенаправляет.

 let unsubscribe;
let allIngredients;
let allRecipes;
let error;

onMount(async () => {
    unsubscribe = searchItems.subscribe((items) => {
        allIngredients = items;
    });

    const ingredients = fixTextArray(allIngredients);
    console.log(ingredients);
    if (ingredients) {
        try {
            const res = await fetch("dev_data/recipes.json");
            if (res.status == 200) {
                allRecipes = await res.json();
            } else {
                error = res.status;
            }
        } catch (err) {
            alert(err);
        }
    } else {
        console.log("CRAP");
    }
});

onDestroy(() => {
    if (unsubscribe) {
        unsubscribe();
    }
});
  

Как я уже упоминал, результат прекрасен, если я ищу с другого маршрута, поэтому моей первоначальной мыслью было заменить onMount, поскольку он уже смонтирован. Но это ничего не дало, поэтому я предполагаю, что Sapper как бы где-то удерживает состояние, чтобы не заставлять перезагружать одни и те же маршруты.

Также, возможно, в разметке может быть что-то, что делает это, поэтому я включаю и это:

 {#if error}
    <h1>{error}</h1>
{:else}
    {#if allRecipes}
        <div class="cards">
            {#each allRecipes as recipe}
                <Card title={recipe.title} link="/{recipe.id}" />
            {:else}Loading{/each}
        </div>
    {:else}No recipes{/if}
{/if}
  

Ответ №1:

Вы можете переместить код, который извлекает рецепты из onMount , и вместо этого установить его в виде отдельного реактивного блока:

 let unsubscribe;
let allIngredients;
let allRecipes;
let error;

$: allIngredients amp;amp; getRecipes(allIngredients)

const getRecipes = (allIngredients) => {
    const ingredients = fixTextArray(allIngredients);
    console.log(ingredients);
    if (ingredients) {
        try {
            const res = await fetch("dev_data/recipes.json");
            if (res.status == 200) {
                allRecipes = await res.json();
            } else {
                error = res.status;
            }
        } catch (err) {
            alert(err);
        }
    } else {
        console.log("CRAP");
    }
}

onMount(async () => {
    unsubscribe = searchItems.subscribe((items) => {
        allIngredients = items;
    });
})

onDestroy(() => {
    if (unsubscribe) {
        unsubscribe();
    }
});
  

Строка $: allIngredients amp;amp; getRecipes(allIngredients) будет выполняться при изменении всех ингредиентов, если она ложная, она остановится, в противном случае она запустит getRecipes с ней и получит рецепты, обновляя другие переменные.

Комментарии:

1. Отлично, спасибо! Не знал, что вы можете создавать реактивные переменные с помощью вызовов функций, действительно полезно!