$ emit от потомка к родителю, Простой счетчик приращений вызывает бесконечный цикл - PullRequest
0 голосов
/ 29 июня 2018

У меня есть заполнить пустой вопрос. Каждый раз, когда ввод правильный, я хочу отправить обратно родителю, чтобы, когда все правильно, я мог отобразить сообщение об успехе.

Я подумал, что могу просто использовать простой счетчик для увеличения на единицу каждый раз, когда $ emit приходит к родителю, но всегда с последней попытки я получаю бесконечный цикл. Я не понимаю, что я делаю не так. Я пытался вычеркнуть мои файлы как можно больше насколько это возможно, чтобы показать, что я считаю актуальным, и вы можете получить представление о том, как это работает. Это что-то с тем, как родительские петли вопроса или что-то?

Спасибо за любую помощь, которую вы можете оказать.

Родительский компонент

Родительский компонент принимает строку JOSN, такую ​​как «В алфавите * _ * есть буквы * _ *», разбивает ее на промежутки для текста и входные данные для * _ *, а затем снова собирает ее. Ответы будут 26 и английский

Частью проблемы в родительской функции является функция questionSuccess ()

<template>
     <div class="interactive interactive-vue-question interactive-vue-question-iv">
     <component 
       :is="buildQuestion(index)"
        ref="ivWrap"
        v-for="(item, index) in questionParts"
        :key="index"
        :questionProps="item.includes('*_*') ? matchedOptions[index] : item"
         @success="questionSuccess">
     </component>
   </div>
</template>

<script>
export default {

name: "iv-v1",
props: ['cData'],
components: {
   ivInput,
   ivText,
},
data: function() {
  return {
    questionParts: [],
    matchedOptions: [],
    options: this.cData.body.options,
    optionsIndex: 0,
    answerBtnText: 'Show Answer(s)',
    showAnswers: false,
    showHints: false,
    showModal: false,
    counter: 0
    }
  },
created () {
    let questionText = this.cData.body.questionText;
    //Split the array at any whitespace character, and groups *_* an returns an array
    this.questionParts = questionText.split(/\s*(\*_\*)\s*/)
    //Filter out any empty array items so there's no extra unkown values
    this.questionParts = this.questionParts.filter(function(e){return e})
    console.log(this.showHints)
  },
  beforeMount: function () {
    //Find all the questionParts
    for(let x =0; x < this.questionParts.length; x++){
      //If input placeholder is found push the corresponding answer from answers into matchedAnswers array
      if(this.questionParts[x].includes("*_*")){
        this.matchedOptions.push(this.options[this.optionsIndex])
        this.optionsIndex++
      }else{
        //If not push an empty string
        this.matchedOptions.push("")
      }
    }
  },
methods: {
    buildQuestion: function (index) {
      //Find the question parts that inlude *_* and push an input to array otherwise push the <span> text </span>
      if(this.questionParts[index].includes('*_*')){
        return ivInput
      }else{
        return ivText
      }
    },
   //
   //THIS IS WHERE I AM TRYING TO COUNT EACH TIME IT RUNS
    questionSuccess: function () {
      this.counter++ 
      console.log(this.counter)
    },
  }
}
</script>

Входной компонент

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

Я испускаю 'success' после isCorrect ()

<template>
    <div class="iv-input-wrap" :class="[{'is-error': isError, 'is-correct': isCorrect}]">
      <input
        ref="iv"
        type="text"
        class="iv-input"
        v-model="userInput"
        :class="[{'is-correct':isCorrect, 'is-error':isError}]"
        :disabled="isCorrect">
    </div>
</template>
<script>
export default {
   name: "iv-input",
  props: [
    'cData',
    'questionProps',
  ],
  data: function() {
    return {
      userInput: "",
      errorMessage: "",
      showPadding: this.questionProps.showPadding,
      displayErrorMessage: this.cData.config.displayErrorMessage,
    }
  },
  computed: {
    isCorrect: function () {
      if(this.isType == true && this.isMatch == true){
       this.$emit('success')
       return true
      }
    },
    isError: function () {
      //If isType has failed and displayErrorMessages are turned on return
      if(this.isType == false && this.displayErrorMessage == true){
        this.$nextTick(function () { 
           new Popper(this.$refs.iv, this.$refs.errorPopper, {
            placement: 'bottom'
          })
        })

        return true
      }
    },
    hideErrorMessage: function () {
      //If Display error message has been turned off
      if(this.isType == false  && this.displayErrorMessage == false) {
        return true
      }
    },
    isType: function () {
      //If the answer type is a string
      let charRegex
      if(this.questionProps.type == 'string'){
        //Check what the accent allowed is
        if (this.questionProps.accent == true) {
          //Allow alpha and accented characters
          charRegex = /^[A-Za-z\u00C0-\u024F]+$/
          this.errorMessage = 'Letters Only'
        } else {
          //Allow alpha characters only
          charRegex = /^[A-Za-z]+$/
          this.errorMessage = 'Letters only'
        }
        //Check if the user has typed anything, if so match input to char-regex
        if(this.userInput.length > 0){
          if (this.userInput.match(charRegex)) {
            return true
          } else {
            return false
          }
        }
      }//End if is string
    },
    isMatch: function () {
      //If isType has not passed then we don't need to proceed
      let checkCase
      if(this.isType == true){
          checkCase = this.userInput.localeCompare(
             this.questionProps.answer, {sensitivity: "case", usage: "search"})
       }
      }//end isType true
    }//end isMatch
  },
}
</script>

1 Ответ

0 голосов
/ 29 июня 2018

Ответ на самом деле был довольно простым.

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

<template>
     <div class="interactive interactive-vue-question interactive-vue-question-iv">
     <component 
       :is="buildQuestion(index)"
        ref="ivWrap"
        v-for="(item, index) in questionParts"
        :key="index"
        :questionProps="item.includes('*_*') ? matchedOptions[index] : item"
         @success.once="questionSuccess">
     </component>
   </div>
</template>
...