#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. Отлично, спасибо! Не знал, что вы можете создавать реактивные переменные с помощью вызовов функций, действительно полезно!