我使用slug参数deckId导航到此页面,我有一个绑定到deckId的下拉菜单。
我的问题是,当导航到页面或刷新所选选项时会消失。变量 DeckId 已定义,但未显示为选定状态。
如果我将其添加到代码中,它就会起作用,
deckId = $page.params.deckId;
const selectElement = document.querySelector('select');
selectElement.value = deckId;
然而,我被告知该解决方案并不理想,并且有更好的方法来做到这一点。有什么更好的办法吗?
import { page } from '$app/stores';
import { goto } from '$app/navigation';
import { Jumper } from 'svelte-loading-spinners';
export let data;
let deckId = $page.params.deckId;
async function handleChangeID(event) {
goto('/homePage/studyDeck/' + event.target.value + '/' + cardStatus + '/');
await getCards();
showBack = false;
}
{#await data.decks}
<span><Jumper /></span>
{:then decks}
<h2 class="font-bold mb-2 text-center text-primary-900 my-auto mr-2">Deck</h2>
<select
class="border border-gray-300 p-2 w-full h-auto rounded text-primary-900 dark:text-primary-400 bg-background-0 dark:bg-primary-60 mr-4"
bind:value={deckId}
on:change={handleChangeID}
>
{#each decks as deck}
<option value={deck.value}>{deck.label}</option>
{/each}
</select>
{/await}
这就是套牌的来源(+layout.js):
export async function load({ fetch }) {
async function getDecks() {
const API_URL = 'http://localhost:3001/Deck';
try {
const response = await fetch(API_URL, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include'
});
const data = await response.json();
return data.map((item) => ({
value: item.deckId,
label: item.deckName
}));
} catch (error) {
console.error('Error:', error);
}
}
return {
decks: getDecks(),
};
}
我尝试过多种变体:
selected={deck.value === deckId}
然后看起来像这样:
<option value={deck.value} selected={deck.value === deckId}>{deck.label}</option>
遗憾的是这并没有改变任何事情
您可以尝试基于
deckId
创建一个新的反应变量。看看 this REPL 有人这样做。它看起来像这样:
// Script
let deckId = $page.params.deckId;
$: selectedDeckId = deckId;
// Markup
<option value={deck.value} selected={deck.value === selectedDeckId}>{deck.label}</option>
否则,为了至少使您的解决方法更清晰一些,您可以绑定该元素。 Svelte 为此提供了
bind:this
指令,该指令优于 document.querySelector
。它看起来像这样:
// Code
import { onMount } from "svelte";
let elSelect;
onMount(() => {
elSelect.value = deckId;
});
// Markup
<select bind:this={elSelect}>...</select>
请注意,仅当所有内容都已加载时才使用
onMount
来引用 DOM 元素(在安装之前,该值为 undefined
)。根据您放置 document.querySelector('select')
的具体位置,它可能仍然有效,因为 DOM 已经加载。但为了避免竞争条件,您应该仅在确保组件已安装后才引用 DOM。