programing

Vue에서 대화 상자가 완료될 때까지 선택 양식을 변경하지 않도록 하는 방법

goodsources 2022. 8. 11. 22:24
반응형

Vue에서 대화 상자가 완료될 때까지 선택 양식을 변경하지 않도록 하는 방법

다양한 옵션을 선택할 수 있는 선택 필드가 있습니다.사용자가 필드를 클릭하여 현재 선택 항목을 변경할 때 사용자에게 변경을 계속할 것인지 확인하도록 프롬프트를 표시해야 합니다. 그러면 사용자가 긴 프로세스를 다시 수행해야 하기 때문입니다.변경을 취소하는 경우, 선택한 옵션이 변경되는 것을 방지해야 합니다.이는 짧은 일시적인 변경이라도 클라이언트에 자동 저장을 트리거하기 때문입니다.따라서 다른 솔루션은 원래 값을 저장하고 변경을 진행시킨 후 필요에 따라 변경을 되돌리기 때문에 작동하지 않는 것으로 보입니다.

이것이 적절한 방법인지는 모르겠지만 선택 필드를 클릭할 때마다 실행되는 함수를 만들기로 했습니다.네이티브를 사용하여 이 문제를 성공적으로 해결했습니다.confirmmethod를 지정합니다.잘 될 것 같아요.confirm님의 동기적인 성질을 통해 변경 내용을 이벤트 청취자가 수신하기 전에 되돌릴 수 있습니다.따라서 기본적으로 변경은 일어나지 않은 것과 같습니다(잘못된 경우에는 정정해 주세요).유감스럽게도, 저는 이 제품을 사용할 수 없습니다.confirm호환성의 이유로.

// This works, but I need to be able to do it without using 'confirm'
handlePotentialOptionChange(e){
  if (this.currentOption !== e.target.value){
    if (!confirm(`Are you sure you want to change the option from ${this.currentOption} to ${e.target.value}? You will be required to redo multiple fields.`)){
      this.selectModel = this.currentOption // If user cancels the change, revert it to the original option. 
    }
  }
}

사용할 수 없기 때문에confirmBuefy의 대화 컴포넌트를 사용하고 있습니다.단, 비동기적으로 실행됩니다.즉, 사용자가 다른 옵션을 선택하려고 하면 대화상자에 응답하기도 전에 옵션 변경이 이루어집니다.아래 코드는 취소 시 변경 내용을 되돌리지만, 그 시점까지 너무 늦었기 때문에 아무 소용이 없습니다.

handlePotentialOptionChange(e){
  if (this.currentOption !== e.target.value){
    this.$dialog.confirm({
      message: `Are you sure you want to change the option from ${this.currentOption} to ${e.target.value}? You will be required to redo multiple fields.`,
      onConfirm: () => this.selectModel = e.target.value,
      onCancel: () => this.selectModel = this.currentOption
    })
  }
}

사용자에게 옵션드롭다운을 표시시켜도 프롬프트에 응답할 때까지 옵션 변경을 비활성화하여 비동기 내에서 옵션을 변경할 수 있습니까?onConfirm그리고.onCancel기능하고 있습니까?아니면 전혀 다른 접근 방식을 사용해야 할까요?감사합니다.

선택 요소와 확인 대화상자를 결합한 새 구성 요소를 생성하고 새 구성 요소가 '입력' 이벤트를 내보내도록 하고(새 선택이 확인된 경우에만), '값' 프로포트를 수신하여 부모가 v-model과 함께 사용할 수 있도록 합니다.

코드 스니펫을 실행하여 다음 예제를 읽어 보십시오.

Vue.component('select-confirm', {
  props: ['value'],

  data: function () {
    return {
      showConfirmationDialog: false,
      unconfirmedValue: 'a'
    }
  },

  methods: {
    cancelSelection () {
      this.showConfirmationDialog = false
    },
    
    confirmSelection () {
      this.$emit('input', this.unconfirmedValue)
      this.showConfirmationDialog = false
    },
    
    showConfirmation (e) {
      this.unconfirmedValue = e.currentTarget.value
      this.showConfirmationDialog = true
    }
  },

  template: `
    <div class="select-confirm">
      <select :value="value" @change="showConfirmation">
        <option value="a">A</option>
        <option value="b">B</option>
      </select>
      <div v-if="showConfirmationDialog" class="confirmation-dialog">
        <p>Are you sure you want to change your selection to '{{ this.unconfirmedValue }}'?</p>
        <button @click="confirmSelection">Yes</button>
        <button @click="cancelSelection">No</button>
      </div>
    </div>
  `
})

new Vue({
  el: '#app',
  data () {
    return {
      confirmedValue: 'a'
    }
  }
})
<script src="https://unpkg.com/vue@2.6.8/dist/vue.min.js"></script>
<div id="app">
  <select-confirm v-model="confirmedValue"></select-confirm>
  <p>Confirmed value is '{{ confirmedValue }}'.</p>
</div>

$refs와 단일 방향 v-bind를 사용한 솔루션을 제안하고 싶습니다.

<template>
    <div>
        <select ref="mySelect" v-bind:value="storedChoice" @input="vOn">
            <option
                v-for="option in selectOptions"
                :value="option.value"
                :key="option.value"
            >
                {{ option.name }}
            </option>
        </select>
    </div>
</template>
<script>
export default {
    data() {
        return {
            selectOptions: [
                { value: 1, name: "Choice 1" },
                { value: 2, name: "Choice 2" },
                { value: 3, name: "Choice 3" },
            ],
            storedChoice: 3,
        };
    },
    methods: {
        vOn(event) {
            const newValue = event.target.value;
            const indexPriorToChange = this.selectOptions.findIndex(
                (el) => el.value === this.storedChoice
            );
            this.$refs.mySelect.options.selectedIndex = indexPriorToChange; // this resets the index to the one resulting from value
            let confirmDialog = new Promise((resolve) => {
                // this promise is a mockup for an asycnc dialog returning true / false
                setTimeout(() => {
                    resolve(true); // resolve true or false
                }, 1500);
            });
            confirmDialog.then((res) => {
                if (res) {
                    this.storedChoice = newValue;
                } else console.log("No changes");
            });
        },
    },
};
</script>

이 아이디어는v-bind 되어 있습니다.v-modelselect필드를 눌러 저장된 데이터의 자동 변경을 차단합니다.에, 「 」 「 」 「 」로 .v-on입력 이벤트에 대해 즉시 액세스하여 선택 필드에 대한 인덱스(사용자의 액션에 따라 브라우저에 의해 변경된 인덱스)를 현재 '실제' 데이터에서 생성된 인덱스로 설정합니다.그런 다음 비동기 검증을 시작하고 검증이 긍정적일 경우 저장된 데이터를 변경하고 선택 필드 자체를 업데이트합니다(그렇지 않을 경우 인덱스를 수동으로 설정할 수 있지만 Vue의 반응성만 사용하여 인덱스를 사용할 수 있습니다).

은, 「이렇게 하면, 할 수 있습니다.Vue warningDOM의 직접 조작에 대해서는 (어떤 이유로 위의 코드는 나에게 도움이 되지 않았지만) 정당한 사용이라고 생각합니다.왜냐하면 우리는 우리의 데이터 모델을 덮어쓰는 데이터를 보여주려고 하지 않기 때문입니다.그 반대로 브라우저는 아직 모델에 저장되지 않은 데이터를 표시하지 못하도록 하고 있기 때문입니다.

여기서 나의 대체 솔루션을 보실 수 있습니다.getter/setterBootstrapVue는 BootstrapVue에 있습니다.

언급URL : https://stackoverflow.com/questions/55696976/how-to-prevent-a-select-form-from-being-changed-until-dialog-completion-in-vue

반응형