Vue.js: значение в цикле v-for не соответствует правильным элементам массива - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь создать простое приложение для запроса ключа от машины для сервисного отдела. Очевидно, что код мог бы быть написан лучше, но это мой третий день с Vue.js. Функция времени, которая вызывается в первом теге p в коде, обновляется каждую минуту, чтобы вести подсчет прошедшего времени. Проблема, с которой я сталкиваюсь, заключается в том, что когда я запрашиваю новый ключ, функция time не следует элементам массива, как предполагалось Например, если нет других запросов, первый запрос, который я отправляю, работает отлично. Однако когда я отправляю новый запрос, истекшее время с моего первого запроса переходит ко второму запросу. Я уверен, что это может быть как-то связано со склеенным кодом, но я перепробовал все, что мог придумать. Любая помощь будет оценена.

<template>
    <div class="row">
        <div class="card col-md-6" v-for="(key, index) in keys" :key="index">
          <div class="card-body">
            <h5 class="card-title">Service Tag: {{ key.service_tag }}</h5>
            <p class="card-text"> {{time}} {{key.reqTimestamp}}min</p>
            <p class="invisible">{{ start(key.reqTimestamp) }}</p>
            <p class="card-text">Associates Name: {{key.requestor_name}}</p>
            <p class="card-text">Model: {{key.model}}</p>
            <p class="card-text">Color: {{key.color}}</p>
            <p class="card-text">Year: {{key.year}}</p>
            <p class="card-text">Comments: {{key.comments}}</p>
            <p class="card-text">Valet: {{key.valet}}</p>
            <input class="form-control" v-model="key.valet" placeholder="Name of the person getting the car...">
            <button
              @click="claimedKey(key.id, key.valet)"
              type="submit" 
              class="btn btn-primary"
              >Claim</button>
              <button v-if="key.valet !== 'Unclaimed'"
              @click="unclaimedKey(key.id, key.valet)"
              type="submit" 
              class="btn btn-primary"
              >Unclaim</button>
            <button class="btn btn-success" @click="complete(key.id)">Complete</button>
          </div>
      </div>
<!-- END OF CARD -->
<!-- START OF FORM -->
      <div class="row justify-content-md-center request">
        <div class="col-md-auto">
          <h1 class="display-4">Operation Tiger Teeth</h1>
          <form class="form-inline" @submit="newKey(service_tag, requestor_name, comments, model, year, color, valet, reqTimestamp)">
            <div class="form-group col-md-6">
              <label for="service_tag">Service Tag: </label>
              <input class="form-control form-control-lg" v-model="service_tag" placeholder="ex: TB1234">
            </div>
            <div class="form-group col-md-6">
              <label for="service_tag">Associates Name: </label>
              <!-- <input class="form-control form-control-lg" v-model="requestor_name" placeholder="Your name goes here..."> -->
              <div class="form-group">
                <label for="exampleFormControlSelect1">Example select</label>
                <select v-model="requestor_name" class="form-control" id="requestor_name">
                  <option>James Shiflett</option>
                  <option>Austin Hughes</option>
                </select>
              </div>
            </div>
            <div class="form-group col-md-6">
              <label for="service_tag">Model: </label>
              <input class="form-control form-control-lg" v-model="model" placeholder="What is the model of the vehicle?">
            </div>
            <div class="form-group col-md-6">
              <label for="service_tag">Color: </label>
              <input class="form-control form-control-lg" v-model="color" placeholder="What is the color of the vehicle?">
            </div>
            <div class="form-group col-md-6">
              <label for="service_tag">Year: </label>
              <input class="form-control form-control-lg" v-model="year" placeholder="What year is the car?">
            </div>
            <div class="form-group col-md-6">
              <label for="service_tag">Comments: </label>
              <input class="form-control form-control-lg" v-model="comments" placeholder="Place any additional comments here...">
            </div>
            <div class="form-group col-md-6 invisible">
              <label for="service_tag">Valet: </label>
              <input v-model="valet">
            </div>
            <div class="form-group col-md-6 invisible">
              <label for="service_tag">Timestamp: </label>
              <input v-model="reqTimestamp">
            </div>
            <div class="col-md-12">
              <button class="btn btn-outline-primary" type="submit">Request A Key</button>
            </div>
          </form>
        </div>
      </div>
    </div>
</template>

<script>
import { db } from "../main";
import { setInterval } from 'timers';
export default {
  name: "HelloWorld",
  data() {
    return {
      keys: [],
      reqTimestamp: this.newDate(),
      service_tag: "",
      requestor_name: "",
      comments: "",
      color: "",
      model: "",
      year: "",
      inputValet: true,
      valet: "Unclaimed",
      state: "started",
      startTime: '',
      currentTime: Date.now(),
      interval: null,
    };
  },
  firestore() {
    return {
      keys: db.collection("keyRequests").where("completion", "==", "Incomplete")
    };
  },
  methods: {
    newKey(service_tag, requestor_name, comments, model, year, color, valet, reqTimestamp, completion) {
      // <-- and here
      db.collection("keyRequests").add({
        service_tag,
        requestor_name,
        comments,
        color,
        model,
        year,
        valet,
        reqTimestamp,
        completion: "Incomplete",
      });
      this.service_tag = "";
      this.requestor_name = "";
      this.comments = "";
      this.color = "";
      this.model = "";
      this.year = "";
      this.reqTimestamp = this.newDate()
    },
      complete(id) {
        db.collection("keyRequests").doc(id).update({
          completion: "Complete"
        })
      },
    // deleteKey(id) {
    //   db.collection("keyRequests")
    //     .doc(id)
    //     .delete();
    claimedKey(id, valet) {
      console.log(id);
      this.inputValet = false
      db.collection("keyRequests").doc(id).update({
        valet: valet,
        claimTimestamp: new Date()
      })
    },
    moment: function () {
    return moment();
    },
    newDate () {
      var today = new Date()
      return today
    },
    updateCurrentTime: function() {
      if (this.$data.state == "started") {
          this.currentTime = Date.now();
        }
      },
      start(timestamp) {
        return this.startTime = timestamp.seconds * 1000
      }      
    },
  mounted: function () {
            this.interval = setInterval(this.updateCurrentTime, 1000);
  },
  destroyed: function() {
            clearInterval(this.interval)
  },
  computed: {
    time: function() {
      return Math.floor((this.currentTime - this.startTime) /60000);
    }
  }
  }
</script>

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

1 Ответ

0 голосов
/ 02 июля 2019

Таким образом, проблемные строки в шаблоне таковы:

<p class="card-text"> {{time}} {{key.reqTimestamp}}min</p>
<p class="invisible">{{ start(key.reqTimestamp) }}</p>

У вызова start есть побочные эффекты, что является основным отрицательным условием для рендеринга компонента.В этом случае он меняет значение startTime, что, в свою очередь, вызывает изменение time.Я немного удивлен, что это не вызывает предупреждение о рекурсии бесконечного рендеринга ...

Вместо этого мы должны просто использовать соответствующие данные для текущего элемента итерации, который вы назвали key.Я бы представил метод, который вычисляет истекшее время с учетом key:

methods: {
  elapsedTime (key) {
    const timestamp = key.reqTimestamp;
    const startTime = timestamp.seconds * 1000;

    return Math.floor((this.currentTime - startTime) / 60000);
  }
}

Вы заметите, что это объединяет аспекты функций start и time.Важно, что он ничего не меняет на this.

Тогда вы можете вызвать его из шаблона:

<p class="card-text"> {{elapsedTime(key)}} {{key.reqTimestamp}}min</p>
...