在 Sapper 的导航中单击重新导航按钮时更新路线
Updating a route when re-navigation button is clicked in nav in Sapper
我有一个包含搜索栏的导航栏,如果该路线当前不是搜索栏的路线,它就可以正常工作。但是,我希望能够在路线内进行搜索,但组件不会重新 运行。
我目前正在 运行 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}
您可以将获取食谱的代码移出 onMount
并将其设置为单独的反应块:
let unsubscribe;
let allIngredients;
let allRecipes;
let error;
$: allIngredients && 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 && getRecipes(allIngredients)
将在allIngredients改变时执行,如果它是假的它会停止,否则它会运行 getRecipes 并得到食谱,更新其他变量。
我有一个包含搜索栏的导航栏,如果该路线当前不是搜索栏的路线,它就可以正常工作。但是,我希望能够在路线内进行搜索,但组件不会重新 运行。
我目前正在 运行 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}
您可以将获取食谱的代码移出 onMount
并将其设置为单独的反应块:
let unsubscribe;
let allIngredients;
let allRecipes;
let error;
$: allIngredients && 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 && getRecipes(allIngredients)
将在allIngredients改变时执行,如果它是假的它会停止,否则它会运行 getRecipes 并得到食谱,更新其他变量。