1
votes

Comment insérer des données calculées vue.js dans des données de formulaire?

<template>
    <form @submit.prevent="uploadMeasurement(measure)">
      <input v-model="measure.length">
      <input v-model="measure.width">
    </form>
</template>

<script>
    export default {
      data() {
        return {
          measure: this.createFreshMeasure(),
        };
      },
      computed: {
        sqftTotal: function() {
          return this.length * this.width;
        }
      },
      methods: {
        uploadMeasurement(measure) {
          MeasurementService.uploadMeasurement(measure)
            .then(...);

              this.measure = this.createFreshMeasure();
            })
            .catch(error => {
              this.error = error.response.data.error;
            });
        },
        createFreshMeasure() {
          return {
            length: this.length,
            width: this.width,
            sqftTotal: this.sqftTotal

          };
        }
</script>
On submit, I'd like to calculate a square footage value using the values placed into the length and width inputs and send all three into the Mongo database.The database is storing a value for sqftTotal when I send a hard-coded value directly over Postman, so it's capable of doing it, but this Vue form isn't accomplishing that task.

7 commentaires

Comment créez-vous une «nouvelle mesure» telle qu'elle se présente?


Honnêtement, vous avez l'impression d'utiliser une masse pour enfoncer un petit clou. Une raison pour laquelle vous ne voulez pas simplement ajouter longueur + largeur et envoyer cela à la base de données au lieu d'utiliser une valeur calculée?


Le composant que je crée est un peu plus compliqué que cela, mais vous avez peut-être encore raison, Arc. Le problème est que lorsque j'ai placé "length * width" dans la nouvelle fonction dans une variation qu'elle n'a pas envoyée. Matt, la fonction de données fraîches est appelée par la fonction de téléchargement.


@Arc et si le sqft doit être affiché dans l'interface graphique? Les accessoires calculés ont été construits pour des scénarios comme celui-ci. Il utilise très certainement le bon outil pour le travail. En outre, pourquoi ne pas simplement calculer le sqft sur le client, vs utiliser les ressources de vos serveurs = P


@connorontheweb ne voulez-vous pas utiliser les valeurs (longueur, largeur) qui se trouvent actuellement dans les entrées? L'exécution de la "fonction de données fraîches" lors de la soumission générerait des valeurs différentes de celles actuellement affichées dans l'interface graphique ...


Je n'ai pas besoin de la superficie en pieds carrés pour afficher de manière réactive. Lorsqu'un nouvel objet est ajouté, l'espace au-dessus du formulaire de contact chargera le tableau d'objets actuel. J'ai juste besoin que ce calcul se produise et l'envoie à la base de données.


Voir ma réponse ci-dessous ... exécutez l'extrait et appuyez sur Soumettre ...


3 Réponses :


-2
votes

Je recommande de nettoyer votre code comme ci-dessous, car Vue a souvent des problèmes lors de l'utilisation des propriétés d'objet comme modèle comme celui-ci

<template>
    <form @submit.prevent="uploadMeasurement()">
      <input v-model="length">
      <input v-model="width">
    </form>
</template>

<script>
    export default {
      data() {
        return {
          length: null,
          width: null,
        };
      },
      computed: {
        sqftTotal: function() {
          return this.length * this.width;
        }
      },
      methods: {
        uploadMeasurement() {
          MeasurementService.uploadMeasurement({
              length: this.length,
              width: this.width,
              sqftTotal: this.sqftTotal
            })
            .then(() => {
              console.log('save success!');
            })
            .catch(error => {
              this.error = error.response.data.error;
            });
        },
    }
</script>


8 commentaires

Le style de code ne répond pas à la question d'OP?


Que voulez-vous dire @MattOestreich, je n'ai utilisé que son code et supprimé la logique en double? OP m'a demandé de publier une valeur calculée, et c'est exactement ce qui se passerait avec mon exemple


Comment les données sont-elles même soumises? Il n'y a aucun événement / action qui soumet réellement le formulaire ... En utilisant this.length et this.width versus this.measure.length et this.measure.width est basé à 100% sur les opinions et est lié au formatage. Des propriétés de formatage comme celles-ci ne résolvent pas du tout le problème d'OP.


Il est transmis au service de mesure en tant qu'objet dans l'exemple ci-dessus. Etes-vous sûr que vous êtes conscient de ce qui se passe dans sa / ma logique. Vous avez ajouté un champ caché, qui est une approche mais totalement inutile étant donné le fonctionnement de Vue ...


Je suppose qu'il se soumettrait en appuyant sur «Entrée» ... Je n'ai ajouté de champ caché nulle part dans ma réponse ... s'il vous plaît, expliquez comment ce champ caché inexistant n'est pas nécessaire car «comment fonctionne Vue» .. Dans comment fonctionne Vue qui juge ma solution inutile. Etes-vous sûr de comprendre ce qui se passe?


Mes excuses, même si un champ masqué serait plus approprié, vous avez ajouté un champ de saisie désactivé, ce qui est toujours inutile étant donné qu'il transmet un objet à son service, qui peut inclure toutes les valeurs, pas seulement les valeurs d'entrée DOM. aborde le problème de l'utilisation des propriétés d'objet comme modèle vuejs.org/v2/guide/reactivity.html


Cela signifie-t-il que tout ce que j'ai à faire est de supprimer une entrée et vous allez voter pour ma réponse ??? Parce que, tu sais, ça en fait soudainement un "champ caché" ...


En attente de vos explications sur " ... qui est une approche mais totalement inutile étant donné le fonctionnement de Vue ... " - De quelle manière Vue fonctionne-t-il qui le rend inutile?



0
votes

Le moyen le plus simple d'accomplir cela serait quelque chose comme ceci. J'ai commenté différentes options dans le code pour aider à expliquer les choses.

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<div id="root"></div>
new Vue({
  el: "#root",
  template: `
  <div>
    <form ref="form">
      <!--<input v-model="measure.length">
      <input v-model="measure.width">-->
      <input v-model="length">
      <input v-model="width">
    </form>
    <button @click.prevent="uploadMeasurement">Submit</button>
  </div>
  `,
  data: {
    //measure: ""
    length: "",
    width: "",
  },
  computed: {
    sqftTotal: function() {
      //return this.measure.length * this.measure.width;
      return this.length * this.width;
    }
  },
  methods: {
    uploadMeasurement() {
      /** This is where you would POST the data **/
      
      // You can either submit the form:
      // -NOTE: '...$refs.form...' below must match the ref
      //        you assign to the <form ref="form"> element.

      // this.$refs.form.$el.submit();

      // ~ OR ~

      // manually POST via fetch, etc:

      // fetch('/url/to/post/to', {
      //   method: 'POST',
      //   body: JSON.stringify({
      //     length: this.measure.length,
      //     width: this.measure.width,
      //     sqftTotal: this.sqftTotal
      //   })
      // })
      
      alert(JSON.stringify({
        //length: this.measure.length, 
        //width: this.measure.width, 
        length: this.length,
        width: this.width,
        sqftTotal: this.sqftTotal
      }));
    },
    createFreshMeasure() {
      this.length = 10;
      this.width = 5;
      //return {
      //  length: 10,
      //  width: 5
      //};
    }
  },
  created() {
    this.createFreshMeasure();
  //this.measure = this.createFreshMeasure();
  }
});


14 commentaires

La chose difficile ici est que je suis dans la portée de this.measure alors que je suis dans la nouvelle fonction. À l'intérieur de cette fonction, il y a this.length, this.width, etc. Alors peut-être que j'ai besoin de passer ce calcul dans cette portée limitée d'une manière ou d'une autre.


Que voulez-vous dire quand vous dites que " vous êtes dans la portée this.measure lorsque vous êtes dans la nouvelle fonction "? Pourquoi est-ce important?


J'appelle this.length, this.width, etc; ce que je suppose dans la plus grande portée signifie cette.longueur.mesure ...


Hein? Maintenant, je suis vraiment confus ... d'où vient le deck ?


Je trouve étrange que this.sqftTotal ne fonctionne pas. this.id fonctionne, et cette valeur est un accessoire passé de la vue au composant et il est logique que this.id fonctionne, mais this.sqftTotal ne fonctionne pas.


Désolé, le projet actuel utilise le deck à la place de la mesure. Je l'ai changé pour cette question. Les documents mongo que j'ajoute sont des données de deck liées (à l'intérieur) d'un document mongo de projet.


Bro de quoi tu parles? Dans votre exemple de code, il n'y a pas de propriétés telles que id ou deck ....


Alors qu'essayez-vous d'accomplir exactement ici? Extrayez-vous des données de Mongo que vous souhaitez afficher dans le navigateur? Ou prenez-vous des données que quelqu'un a saisies dans les entrées et les publiez-vous sur Mongo?


Voici comment cela se passe dans l'exemple de la vie réelle. L'utilisateur crée un «projet», puis crée un certain nombre de «pont» (mesures de pont) liés à ce projet. C'est pour une entreprise de construction


Les decks appartiennent à Project, donc l'id est l'ID de projet transmis comme accessoire pour créer cette relation.


Maintenant que je n'en suis pas sûr, vous devrez fournir un exemple plus détaillé dans votre question si vous voulez de l'aide pour tout cela ... En ce qui concerne la possibilité d'utiliser une propriété calculée pour déterminer le sqft, et un moyen de soumettre / POST ces données, ma réponse fournit cela.


J'apprécie votre contribution ici, je devrai trouver une façon plus claire d'illustrer ce dont je parle.


J'ai compris, supprimé l'argument «mesure» de la méthode uploadMeasurement, déclaré «mesure» avant l'appel de service et déclaré «mesure.sqftTotal = this.sqftTotal» en dessous.


C'est littéralement exactement ce que je faisais. Au lieu de this.length (et width), vous utilisiez this.measure.length (et width) ...... Je l'ai montré dans ma réponse (sous la méthode uploadMeasurement () ) ... regardez comment je suis alert dans les données ..... Je viens de faire les changements nécessaires à mon exemple pour en faire exactement ce que vous recherchiez ... Je n'ai commenté que l'ancien code afin que vous puissiez comprendre et visualiser la différence. Au lieu d'utiliser un objet mesure pour stocker length et width vous les stockez simplement tous les deux directement sous forme de données .. il n'y a aucun changement dans la logique.



0
votes
  methods: {
    uploadMeasurement() {
      let measure = this.measure;
      measure.sqftTotal = this.sqftTotal;
      MeasurementService.uploadMeasurement(measure)
      ...
Got it, thanks to everyone for your input. Had to remove the argument from the method and declare it before the service call.

0 commentaires