Получение динамической c v-модели для сравнения с данными - VueJS и Vuelidate - PullRequest
0 голосов
/ 30 апреля 2020

Я работаю над простой формой, которая показывает 3 элемента

  1. Начальное поле штрих-кода
  2. Конечное поле штрих-кода
  3. Поле метки

Пользователь вводит 2 штрих-кода в каждое поле. Первые 2 цифры значения barcodeEnd сравниваются с данными allBarcodePrefixes, чтобы увидеть, есть ли совпадение, и печатает название соответствующего агентства или «Агентство не найдено», если совпадения нет. Если совпадения нет, форма останавливается на этом (пользователь должен исправить запись штрих-кода), но если он находит совпадение, он выводит новую строку с вновь созданным набором полей и v-моделей

Это сработало все в порядке, пока я не сделал v-модели динамическими c, поэтому я могу независимо управлять каждой записью для проверки и значения

ПРОБЛЕМА Происходят две странные вещи, мне нужна помощь с парнями.

  1. Начальное поле штрих-кода очищается, когда я размываю и в следующее поле ввода. Потом, когда я что-то ввожу туда, это возвращается! У меня тоже есть чистая консоль, поэтому я понятия не имею, что происходит.
  2. Метод showAgencyName() должен получить v-модель и сравнить ее с данными, чтобы получить название агентства. Но моя v-модель является динамической c и в строковом литерале. Я не уверен, как получить это значение

У меня есть код в codepen , чтобы вы могли проверить его и понять, что я имею в виду. Я поместил функцию onAddBarcodes в строку с ошибками, чтобы вы могли видеть, что она проверяется правильно (эта часть работает). В конце концов, эта строка будет удалена, так как она должна проверяться только для minLength и maxLength после того, как она сначала была подтверждена для агентства.

    <div id="q-app">
        <div class="q-pa-md">
          <div>
            <div v-for="(barcode, index) in barcodes" :key="index">
              <div class="full-width row no-wrap justify-start items-center q-pt-lg">
                <div class="col-3">
                  <label>Starting Roll #:</label>
                  <q-input outlined square dense v-model="$v[`barcodeStart${index}`].$model"></q-input>

                  <div class="error-msg">
                    <div v-if="!$v[`barcodeStart${index}`].maxLength || !$v[`barcodeStart${index}`].minLength">
                      <span> Must be exactly 9 characters. </span>
                    </div>
                  </div>
                </div>

                <div class="col-3">
                  <label>Ending Roll #:</label>
                  <q-input outlined square dense v-model="$v[`barcodeEnd${index}`].$model" @change="showAgencyName(barcode)"></q-input>
                  <div class="error-msg">
                    <div v-if="!$v[`barcodeEnd${index}`].maxLength || !$v[`barcodeEnd${index}`].minLength">
                      <span> Must be exactly 9 characters. </span>
                    </div>
                  </div>
                </div>

                <div class="col-3">
                  <label>Agency:</label>
                  <div v-if="barcode.agencyName">
                    {{ barcode.agencyName }}
                  </div>
                  <div v-else></div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>


      Vue.use(window.vuelidate.default)
      const { required, minLength, maxLength } = window.validators

      new Vue({
        el: '#q-app',
        data () {
          return {
            barcodes: [
              {
                barcodeStart: "",
                barcodeEnd: "",
                agencyName: ""
              }
            ],
            newPackage: "",
            reset: true,
            allBarcodePrefixes: {
              "10": "Boston",
              "11": "New York",
              "13": "Houston",
              "14": "Connecticut",
              "16": "SIA",
              "17": "Colorado",
              "18": "Chicago"
            }
          }
        },
        validations() {
          const rules = {};
          this.barcodes.forEach((barcode, index) => {
            rules[`barcodeStart${index}`] = {
                minLength: minLength(9),
                maxLength: maxLength(9)
            };
          });

          this.barcodes.forEach((barcode, index) => {
            rules[`barcodeEnd${index}`] = {
                minLength: minLength(9),
                maxLength: maxLength(9)
            };
          });
          return rules;
        },
        methods: {
          onAddBarcodes() {
            // creating a new line when requested on blur of barcodeEnd
            const newBarcode = {
              barcodeStart: "",
              barcodeEnd: "",
              agencyName: ""
            };
            this.barcodes.push(newBarcode);
          },

          showAgencyName(barcode) {
            var str = barcode.barcodeEnd; // I need to pull the v-model value
            var res = str.substring(0, 2); //get first 2 char of v-model
            if (this.allBarcodePrefixes[res] == undefined) {
              //compare it to data
              barcode.agencyName = "Agency not found"; //pass this msg if not matched
              this.onAddBarcodes(); //adding it to the fail just for testing
            } else {
              barcode.agencyName = this.allBarcodePrefixes[res]; //pass this if matched
              this.onAddBarcodes(); //bring up a new line
            }
          },
        }
      })

Заранее спасибо!

1 Ответ

1 голос
/ 30 апреля 2020

Что вы можете сделать, это установить v-модель для объекта в вашем v-for l oop. Чтобы это выглядело следующим образом.

<q-input outlined square dense v-model="barcode.barcodeStart"></q-input>

и

<q-input outlined square dense v-model="barcode.barcodeEnd"></q-input>

Таким образом они обновляют объект штрих-кода и благодаря тому, что он является наблюдаемой, ваша функция showAgencyName может оставаться неизменной is, и объект штрих-кода в нем будет обновлен.

EDIT

Когда вы вызываете событие onchange, вы можете затем пройти через индекс

@change="showAgencyName(barcode, index)"

, затем в вашем showAgencyName Вы можете получить доступ к проверке с помощью this.$v.

Чтобы убедиться, что правила прошли, вам нужно обновить $model. Как это

 this.$v[`barcodeStart${index}`].$model = barcode.barcodeStart
this.$v[`barcodeEnd${index}`].$model = barcode.barcodeEnd

// Check for errors
if (this.$v[`barcodeEnd${index}`].$error) {
   return
}
...