Двусторонняя привязка флажка не происходит

Для кода, опубликованного ниже, компонент vue является дочерним компонентом и размещается в определенном родительском компоненте. Когда я делаю привязку двумя способами через vModelCheckGeoTIFFOverlayBandAverages, внося изменение в compPropsVModelCheckGeoTIFFOverlayBandAverages, изменения не отражаются в родительском компоненте.

Я делаю привязку checkbox неправильно?

код:

<template>
    <cds-checkbox id = "idCheckboxGeoTIFFOverlayBandAveragesContainer">
        <label id = "idTextGeoTIFFOverlayBandAverages">{{ tempTextBandAverages }}</label>
        <input
            type = "checkbox"
            :value = "compPropsVModelCheckGeoTIFFOverlayBandAverages"
            @input = "$emit('update:compPropsVModelCheckGeoTIFFOverlayBandAverages', $event.target.checked)"
            :disabled = "isCheckboxGeoTIFFOverlayBandAveragesDisabled"
            :checked = "compPropsVModelCheckGeoTIFFOverlayBandAverages"
            @change = "onCheckboxGeoTIFFOverlayBandAveragesChanged"
        />
    </cds-checkbox>
</template>

<script>
import { GeoTIFFOverlaySettingsConstants } from '../../../resources/....';
import { StoreOnCheckboxBandAveragesStatusChanged } from '../../../../../...';

let msg = null;

export default {
    name: 'SentinelHubGeoTIFFOverlayBand1',
    data() {
        return {
            refStoreOnCheckboxBandAveragesStatusChanged: StoreOnCheckboxBandAveragesStatusChanged,
            isCheckboxChecked: false,
            tempTextBandAverages: GeoTIFFOverlaySettingsConstants.CONST_STRING_BAND_1_AVERAGES.description,
        };
    },
    components: {},
    props: {
        isCheckboxGeoTIFFOverlayBandAveragesDisabled: {
            type: Boolean,
            default: true,
        },
        vModelCheckGeoTIFFOverlayBandAverages: {
            type: Boolean,
            default: null,
        },
    },
    emits: {
        'update:vModelCheckGeoTIFFOverlayBandAverages':null,
    },
    computed: {
        compPropsVModelCheckGeoTIFFOverlayBandAverages: {
            get() {
                return this.vModelCheckGeoTIFFOverlayBandAverages;
            },
            set(value) {
                this.$emit('update:vModelCheckGeoTIFFOverlayBandAverages', value);
            },
        },
    },
    watch: {
        isCheckboxChecked(newVal, oldVal) {
            this.compPropsVModelCheckGeoTIFFOverlayBandAverages = newVal;
        },
    },
    methods: {
        async onCheckboxGeoTIFFOverlayBandAveragesChanged() {
            this.isCheckboxChecked = !this.isCheckboxChecked;
            await this.refStoreOnCheckboxBandAveragesStatusChanged.actions.init();
            this.refStoreOnCheckboxBandAveragesStatusChanged.setters.set(this.isCheckboxChecked);
        },
    },
};
</script>

объяснил выше в вопросе

Как отмечалось в предыдущих вопросах, существует неразбериха с записываемыми вычислениями и прямым использованием реквизитов и событий, аналогичные проблемы возникали и там. Здесь вам действительно не нужна записываемая возможность. Это усложняет задачу. Сложные имена тоже не помогают. Не принято давать длинные имена, такие как «vModelCheckGeoTIFFOverlayBandAverages», они сбивают с толку и их трудно различить. Уже существует соглашение, которому следует следовать для v-модели, реквизита «modelValue» и события «update:modelValue». Этот компонент работает с 1 значением и соответствует этому соглашению.

Estus Flask 01.07.2024 15:04

@EstusFlask, не могли бы вы предоставить расширенную версию кода, чтобы я мог использовать ее в качестве шаблона или ссылки для любого будущего использования?

Amr 01.07.2024 15:08

Причина, по которой здесь это не работает, заключается в том, что вы не используете set() в записываемых вычислениях, что делает его бесполезным. Вместо этого генерируется событие update:compPropsVModelCheckGeoTIFFOverlayBandAverages, это «compProps...» — это имя вычисляемого значения, а имя события — «update:vModelCheckGeoTIFFOverlayBandAverages». То, что неправильное наименование приводит к ошибкам и заставляет вас путать вещи, предполагает, что это реальная проблема, а не просто вопрос вкуса. Я бы предложил использовать для этого компонента код, который я разместил в предыдущих вопросах. Я совершенно уверен, что он работоспособен и имя исправлено, эти вопросы, вероятно, были удалены?

Estus Flask 01.07.2024 15:11

@EstusFlask ценю вашу помощь, но можно ли перевести слова из вашего последнего комментария в код, пожалуйста, это будет более полезно и здорово, пожалуйста

Amr 01.07.2024 15:25

@EstusFlask, к сожалению, я не могу найти вопросы, на которые вы намекали. Ссылаясь на ваш последний комментарий, вы упомянули, что я не использовал «set» записываемого вычисляемого свойства! Но я им воспользовался, я ошибаюсь?

Amr 01.07.2024 16:15

Поправляюсь, похоже, был другой аккаунт и вопросы не удалились. Также вы правы насчет set(), он срабатывает здесь this.isCheckboxChecked = !this.isCheckboxChecked, поэтому проблема может быть в родителе.

Estus Flask 01.07.2024 16:28

Что касается предыдущего комментария, то я разобрался, но уже забыл, когда писал. Проблема в том, что вы ожидаете вызова set() @change. Но он не вызывается на входах. Вызывается только @input и генерирует событие update:compPropsVModelCheckGeoTIFFOverlayBandAverages, которое ничего не делает. Отсутствие работы с низкоуровневой реализацией DOM является веской причиной придерживаться v-модели для собственных элементов, как отмечено в ответе.

Estus Flask 01.07.2024 16:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
98
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ввод генерирует событие update:compPropsVModelCheckGeoTIFFOverlayBandAverages, а имя события — update:vModelCheckGeoTIFFOverlayBandAverages. Это показывает проблему с длинными именами. v-model уже предлагает соглашение, реквизит «modelValue» и событие «update:modelValue». Пока компонент имеет дело с одним значением, эти имена однозначны и могут использоваться традиционно.

По-прежнему полезно использовать его с v-model с нативными элементами, такими как input, вместо прямого использования реквизитов и событий, поскольку это позволяет пропустить низкоуровневые детали, такие как $event.target.checked, и сделать код короче и менее подверженным ошибкам.

Неясно, требуется ли для компонента собственное локальное состояние. Если в этом нет необходимости, data() для состояния компонента не нужен, а имена можно сделать короткими и понятными:

<label id = "idTextGeoTIFFOverlayBandAverages">{{ labelText }}</label>
<input
  type = "checkbox"
  v-model = "isChecked"
  :disabled = "disabled"
/>

и

props: {
    modelValue: {
        type: Boolean,
        default: false,
    },
    disabled: {
        type: Boolean,
        default: false,
    },
},
emits: {
    'update:modelValue':null,
},
data() {
    return {
        labelText: GeoTIFFOverlaySettingsConstants.CONST_STRING_BAND_1_AVERAGES.description,
    };
},
computed: {
    isChecked: {
        get() {
            return this.modelValue;
        },
        set(value) {
            this.$emit('update:modelValue', value);
        },
    },
},
watch: {
    isChecked(newVal, oldVal) {
      // can be used to do anything on value updates, e.g. sync a store
    },
}

И предполагается использовать как:

Или без v-model использовать проще, чем с input:

<SentinelHubGeoTIFFOverlayBand1
  :modelValue = "someValue"
  @update:modelValue = "updateSomeValue"
  :disabled = "someDisabled"/>

Большое спасибо, я признаю, как только протестирую

Amr 01.07.2024 16:41

Но почему, когда я следую той же схеме, что упомянута в моем первоначальном вопросе, с кнопкой чтения это работает? Есть ли особенности у флажка, пожалуйста

Amr 01.07.2024 17:05

Можете ли вы уточнить по поводу кнопки чтения, какую именно вы имеете в виду?

Estus Flask 01.07.2024 17:18

Извините, я имел в виду радиокнопку. Это была автокоррекция. Я имею в виду, что в своем первоначальном вопросе я следовал той же схеме, но с переключателями, и он работал так, как ожидалось.

Amr 01.07.2024 18:55

Принципиальной разницы между ними нет, нужно проверять, чем они отличались. Это может быть работоспособно с некоторыми отличиями. Основная проблема заключается в том, что весь код излишне запутан, позволяет легко совершать ошибки и затрудняет их поиск.

Estus Flask 01.07.2024 19:50

Утром я вношу изменения в исходный вопрос, потому что значение, которое я меняю в дочернем компоненте, несмотря на то, что я использовал тот же код в своем исходном вопросе, отражается в subparent component, но никогда не отражается в grand or the main parent. мне просто обновить вопрос или опубликовать заново, пожалуйста

Amr 02.07.2024 07:47

Конечно, рассмотрите возможность публикации нового вопроса, добавьте ссылку на этот вопрос, если он связан.

Estus Flask 02.07.2024 10:45

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