如何让 select 在 svelte 中显示值

How to get a select to show values in svelte

我的 svelte 应用程序中有一个 select。我无法让它显示它的初始值 (default_car) 或者,在我点击一辆汽车后,selected_car

REPL

App.svelte

<Car {cars} on:message={carChanged} />
<div>
    <button on:click={getDataStore}>Get data</button>
</div>

<script>
    import Car from './Cars.svelte'
    import { getBlankCars, getCarData } from './store.js'

    let cars = getBlankCars();
    let car;

    function carChanged(event) {
        car = event.detail.value;
        console.log('selected car:', car);
    }

    function getDataStore() {
        cars = getCarData();
    }
</script>

Cars.svelte

<select bind:value={selected_car} on:click={selectCar}>
    {#each car_list as car}
        <option value={car}>
            {car}
        </option>
    {/each}
</select>

<script>
    import { createEventDispatcher } from 'svelte';
    const dispatch = createEventDispatcher();

    let started = false;
    export let cars;
    $cars = $cars;

    let car_list;
    $: car_list = carList($cars);

    let default_car = 'BMW';

    let selected_car;
    $: selected_car = getInitialCar($cars)
    $: selected_car = default_car

    function getInitialCar() {
        if (!started) {
            selected_car = default_car;
            if (selected_car) {
                started = true;
                selectCar();
            }
        }
        selected_car = default_car
    }

    function carList(cars) {
        let car_list = [];
        for (const [key, value] of Object.entries(cars)) {
            car_list.push(key);
        }
        return car_list;
    }

    function selectCar() {
        dispatch('message', {
            value: selected_car
        });
    }
</script>

store.js

import { writable } from 'svelte/store'

let blank_cars = {}
let raw_cars = {'Audi': 'red', 'Aston Martin': 'silver', 'BMW':'blue', 'Bugatti': 'black', 'Hillman': 'green'}

export function getBlankCars() {
    return writable(blank_cars)
}

export function getCarData() {
    return writable(raw_cars)
}

如何才能让 select 显示该值?

我认为您可以将 Cars.svelte 中的代码简化为 REPL - 这个功能是否符合您的要求?
三件事要提

  • 如果您有一个对象作为存储值并希望在 {#each} 循环中显示内容,您不必生成一个新数组,但可以直接在每个对象中迭代 {#each Object.keys($cars) as car}{#each Object.entries($cars) as [key, value]}
  • on:click更改为on:change={selectCar}
  • html 下方的 <script> 块是不寻常的 ~ 更常见的顺序(如 Svelte tutorial 中)是脚本 - html - style/css
<script>
    import { createEventDispatcher } from 'svelte';
    const dispatch = createEventDispatcher();

    export let cars;

    let selected_car = 'BMW'; // set default value here

    function selectCar() {
        dispatch('message', {
            value: selected_car
        });
    }
</script>

<select bind:value={selected_car} on:change={selectCar}>
<!--    reduce code by directly iterating $cars via Object.entries/.keys/.values(obj) -->
    {#each Object.keys($cars) as car}
    <option value={car}>
        {car}
    </option>
    {/each}
</select>