select 值绑定和 svelte-i18n 集成问题
select value binding and svelte-i18n integration problem
我正在处理的事情似乎有点超出我的知识范围...
它是关于 select 值绑定的。在下面,这是一段简单的和平代码,可以在经典的 svelte SPA 中完美运行。
<script>
let countrySelected = {
code: 'BE',
name: 'Belgium',
};
const countries = [
{
code: 'FR',
name: 'France',
},
{
code: 'BE',
name: 'Belgium',
},
{
code: 'GA',
name: 'Gabon',
},
];
</script>
<select bind:value={countrySelected}>
{#each countries as country}
<option value={country} selected={country.code === countrySelected.code}>
{country.name}
</option>
{/each}
</select>
但无论出于何种原因,当它在使用 svelte-i18n
npm
包的 sveltekit
应用程序中工作时,它不再起作用。
/src/routes/__layout.svelte
<script>
import { setupI18n, isLocaleLoaded } from '$lib/services/i18n.js';
$: if (!$isLocaleLoaded) {
setupI18n({ withLocale: 'fr-FR' });
}
</script>
{#if !$isLocaleLoaded}
Please wait...
{:else}
<main>
<slot />
</main>
{/if}
/src/lib/services/i18n.js
/src/lib/services/i18n.js
的代码来自:
https://phrase.com/blog/posts/how-to-localize-a-svelte-app-with-svelte-i18n/
&
https://lokalise.com/blog/svelte-i18n/
import { derived } from 'svelte/store';
import { dictionary, locale, _, date, time, number } from 'svelte-i18n';
const MESSAGE_FILE_URL_TEMPLATE = 'http://localhost:3000/lang/{locale}.json';
let cachedLocale;
async function setupI18n({ withLocale: _locale } = { withLocale: 'en-GB' }) {
const messsagesFileUrl = MESSAGE_FILE_URL_TEMPLATE.replace(
'{locale}',
_locale
);
const res = await fetch(messsagesFileUrl);
const messages = await res.json();
dictionary.set({ [_locale]: messages });
cachedLocale = _locale;
locale.set(_locale);
}
// Before any locale is set, svelte-i18n will give locale an object type.
// Once it is correctly set, the libray will set locale
// to the code of the active locale, e.g. "en", a string type.
// We check for this in our devired store, and make sure that isLocaleLoaded‘s value
// is true only after i18n initialization is successful.
const isLocaleLoaded = derived(locale, $locale => typeof $locale === 'string');
export { _, locale, setupI18n, isLocaleLoaded, date, time, number };
问题:
index.svelte 文件中的 <select>
元素应显示“比利时”,因为:
countrySelected = { code: 'BE', name: 'Belgium', }
问题在于,在 __layout.svelte
中,svelte-i18n
会在项目 selected 之后进行某种刷新,因此看起来什么都没有 selected。
这可能是因为我在我的项目中集成 svelte-i18n 的方式,因为我只理解粗略的笔触,但再一次......细节决定成败 :D
非常感谢您的帮助。你可以克隆这个 repos,它会更容易理解:
git clone https://github.com/BigBoulard/sveltekit-sveltei18n
npm i
npm run dev
对于您的示例,如果您在浏览器中检查 select
元素,则 selected
属性未设置在任何 option
.
上
Svelte 有一种非常简单易用的方法来设置初始 selected
值。
在将值绑定到 select
元素时,它会自动处理 option
元素上的必需属性。
您示例中的问题是,countrySelected
看起来与 countries
数组中的 object/dictionary 相同,但实际上是一个新对象,因此 Svelte 不能 select 它。
这个例子应该有效:
<script>
const countries = [
{
code: 'FR',
name: 'France',
},
{
code: 'BE',
name: 'Belgium',
},
{
code: 'GA',
name: 'Gabon',
},
];
let countrySelected = countries.find(x => x.code === 'BE');
</script>
<select bind:value={countrySelected}>
{#each countries as country}
<option value={country}>
{country.name}
</option>
{/each}
</select>
我正在处理的事情似乎有点超出我的知识范围...
它是关于 select 值绑定的。在下面,这是一段简单的和平代码,可以在经典的 svelte SPA 中完美运行。
<script>
let countrySelected = {
code: 'BE',
name: 'Belgium',
};
const countries = [
{
code: 'FR',
name: 'France',
},
{
code: 'BE',
name: 'Belgium',
},
{
code: 'GA',
name: 'Gabon',
},
];
</script>
<select bind:value={countrySelected}>
{#each countries as country}
<option value={country} selected={country.code === countrySelected.code}>
{country.name}
</option>
{/each}
</select>
但无论出于何种原因,当它在使用 svelte-i18n
npm
包的 sveltekit
应用程序中工作时,它不再起作用。
/src/routes/__layout.svelte
<script>
import { setupI18n, isLocaleLoaded } from '$lib/services/i18n.js';
$: if (!$isLocaleLoaded) {
setupI18n({ withLocale: 'fr-FR' });
}
</script>
{#if !$isLocaleLoaded}
Please wait...
{:else}
<main>
<slot />
</main>
{/if}
/src/lib/services/i18n.js
/src/lib/services/i18n.js
的代码来自:
https://phrase.com/blog/posts/how-to-localize-a-svelte-app-with-svelte-i18n/ & https://lokalise.com/blog/svelte-i18n/
import { derived } from 'svelte/store';
import { dictionary, locale, _, date, time, number } from 'svelte-i18n';
const MESSAGE_FILE_URL_TEMPLATE = 'http://localhost:3000/lang/{locale}.json';
let cachedLocale;
async function setupI18n({ withLocale: _locale } = { withLocale: 'en-GB' }) {
const messsagesFileUrl = MESSAGE_FILE_URL_TEMPLATE.replace(
'{locale}',
_locale
);
const res = await fetch(messsagesFileUrl);
const messages = await res.json();
dictionary.set({ [_locale]: messages });
cachedLocale = _locale;
locale.set(_locale);
}
// Before any locale is set, svelte-i18n will give locale an object type.
// Once it is correctly set, the libray will set locale
// to the code of the active locale, e.g. "en", a string type.
// We check for this in our devired store, and make sure that isLocaleLoaded‘s value
// is true only after i18n initialization is successful.
const isLocaleLoaded = derived(locale, $locale => typeof $locale === 'string');
export { _, locale, setupI18n, isLocaleLoaded, date, time, number };
问题:
index.svelte 文件中的 <select>
元素应显示“比利时”,因为:
countrySelected = { code: 'BE', name: 'Belgium', }
问题在于,在 __layout.svelte
中,svelte-i18n
会在项目 selected 之后进行某种刷新,因此看起来什么都没有 selected。
这可能是因为我在我的项目中集成 svelte-i18n 的方式,因为我只理解粗略的笔触,但再一次......细节决定成败 :D
非常感谢您的帮助。你可以克隆这个 repos,它会更容易理解:
git clone https://github.com/BigBoulard/sveltekit-sveltei18n
npm i
npm run dev
对于您的示例,如果您在浏览器中检查 select
元素,则 selected
属性未设置在任何 option
.
Svelte 有一种非常简单易用的方法来设置初始 selected
值。
在将值绑定到 select
元素时,它会自动处理 option
元素上的必需属性。
您示例中的问题是,countrySelected
看起来与 countries
数组中的 object/dictionary 相同,但实际上是一个新对象,因此 Svelte 不能 select 它。
这个例子应该有效:
<script>
const countries = [
{
code: 'FR',
name: 'France',
},
{
code: 'BE',
name: 'Belgium',
},
{
code: 'GA',
name: 'Gabon',
},
];
let countrySelected = countries.find(x => x.code === 'BE');
</script>
<select bind:value={countrySelected}>
{#each countries as country}
<option value={country}>
{country.name}
</option>
{/each}
</select>