Alpine JS неправильно обновляет x-модель

У меня проблема с выбранным вариантом в простой форме Alpine. Мой selectbox получает свои значения из api. Х-модель устанавливается перед выборкой. Поле выбора иногда показывает правильное выбранное значение, а иногда нет. Даже если я установлю значение после выборки, выбранный вариант (всегда) не выбран. Как мне убедиться, что всегда установлено правильное выбранное значение?

Примечание: значение поля выбора 2 зависит от значения, установленного первым. Но если оба установлены, они оба должны отображать правильное выбранное значение, заданное в valueA и valueB.

Это моя функция

<script>
function alpineSelectFunction() {
    return {
        valueA: '100',
        arrayA: [],
        valueB: '101',
        arrayB: [],
        isLoading: false,
        apiUrl: "apiurl",
        fetchArrayA() {
            fetchUrl = this.apiUrl + `arrayA.json`;
            this.isLoading = true;
            fetch(fetchUrl)
                .then(res => res.json())
                .then(data =>  this.arrayA = data.data);
            this.isLoading = false;
        },
        fetchArrayB() {
            fetchUrl = this.apiUrl + `arrayB.json?id=${this.valueA}`;
            this.isLoading = true;
            fetch(fetchUrl)
            .then(res => res.json())
            .then(data => this.arrayB = data.data);
            this.isLoading = false;
        },
        init() {
            this.fetchArrayA();
            this.fetchArrayB();
        }
    }
}
</script>

Это HTML

<div x-data="alpineSelectFunction()" x-init="init()">
    <select name="valueA" x-model="valueA" :disabled="isLoading" x-on:input.debounce.750="fetchArrayB()">
        <option value="">Choose...</option>
        <template x-for="option in arrayA">
            <option :value="option.id" x-text="option.title"></option>
        </template>
    </select>

    <select name="valueB" x-model="valueB" :disabled="isLoading">
        <option value="">Choose...</option>
        <template x-for="option in arrayB">
            <option :value="option.id" x-text="option.title"></option>
        </template>
    </select>
</div>

1 ответ

Решение

В этом случае у вас проблема, потому что x-model бежит раньше x-for.

Чтобы обойти это, вы можете привязать к selected:

<div x-data="alpineSelectFunction()" x-init="init()">
    <select name="valueA" x-model="valueA" :disabled="isLoading" x-on:input.debounce.750="fetchArrayB()">
        <option value="">Choose...</option>
        <template x-for="option in arrayA">
            <option :value="option.id" :selected="option.id === valueA" x-text="option.title"></option>
        </template>
    </select>

    <select name="valueB" x-model="valueB" :disabled="isLoading">
        <option value="">Choose...</option>
        <template x-for="option in arrayB">
            <option :value="option.id" :selected="option.id === valueB x-text="option.title"></option>
        </template>
    </select>
</div>

Ключевым кодом являются следующие строки:

<option :value="option.id" :selected="option.id === valueA" x-text="option.title"></option>

<option :value="option.id" :selected="option.id === valueB x-text="option.title"></option>

Вы можете найти обсуждение / объяснение проблемы (и другое возможное решение) на https://github.com/alpinejs/alpine/issues/495.

Другие вопросы по тегам