javascript - 如何从 vue 对话框/模式中获取用户输入

标签 javascript vue.js

我有一个 MyList.vue,它由我的 app.vue 直接导入。 MyList.vue 不包含子组件,它只导入:

import store from "../store/store";
import { USER_FETCHLIST } from "../store/actions/user";

数据如下所示:

export default {
  data () {
    return {
      tableData: [],
      tableheader: []
    }
  },
  created: function(){
    store.dispatch(USER_FETCHLIST).then((res) => {

        this.tableData = res["data"]["tableData"]
        this.tableHeader = res["data"]["tableHeader"]
    })
},
  methods: {
    changeRecord: function(element){
      console.log(element)
    }
  }

}

MyList.vue 具有以下 bootstrap-vue 模式标记:

<template v-for="(element, index) in tableData">
   <tr>
    //rest of the markup generating the columns carrying the data
      <td>
        <button v-on:click="changeRecord(element)" v-b-modal="`modal-${index}`">Aendern</button>

        <b-modal :id="'modal-' + index" title="BootstrapVue">
      <template v-for="(value, name) in element">

        <template v-if="typeof value==='object'">
          <template v-for="(nestedValue, nestedName) in value">
            <span>{{nestedName}}</span>
            <input type="text" :value="nestedValue" :class="'editFieldDivision-' + index">
          </template>
        </template>

          <template v-else>
            <span>{{name}}</span>
            <input type="text" :value="value" :class="'editFieldDivision-' + index">
          </template>
     </template>
    </b-modal>
  </td>
</tr>
</template>

单击按钮时的最终结果是此对话框:

/image/3yomu.jpg

对话框可能有更多或更少的输入字段,具体取决于它从后端接收的数据。

但是,此对话框应该允许用户将更改应用于后台列表中的相应记录。 由于我对 vue 很陌生,所以我不知道“抓取”用户输入的“vue 方法”是什么。我应该使用 v 模型吗?如果是这样,我该怎么做,因为插入的数据/可观察量是动态插入的。最后将数据放入一维,其中key-value以各个输入字段的“标签”为key,以各个输入字段的值作为value。

此外,如果用户放弃对话框,则对话框内的更改不应应用于前端的数据集。

最佳答案

这是实现您正在寻找的目标的一种方法。

保留对原始对象的引用,并创建一个副本。 然后,您将在模式内的输入中使用副本,这样您就不会修改原始对象。 然后在隐藏事件中,检查是否按下了“确定”按钮,如果是,则将所有值从副本复制到原始对象。

如果单击“取消”(或以其他方式关闭模式),您只需清除所选对象和副本即可。

此解决方案使用 lodash.set方法,因此您需要将其包含在您的项目中。

我还将您的模式移出了表格循环。 由于您一次只能编辑一条记录,因此您的页面上实际上只需要一个模式。

new Vue({
  el: "#app",
  data() {
    return {
      data: [{
          Internal_key: "TESTKEY_1",
          extensiontable_itc: {
            description_itc: "EXTENSION_ITC_1_1",
            description_itc2: "EXTENSION_ITC_1_2",
          },
          extensiontable_sysops: {
            description_sysops: "EXTENSION_SYSOPS_1"
          }
        },
        {
          Internal_key: "TESTKEY_2",
          extensiontable_itc: {
            description_itc: "EXTENSION_ITC_2_1",
            description_itc2: "EXTENSION_ITC_2_2",
          },
          extensiontable_sysops: {
            description_sysops: "EXTENSION_SYSOPS_2_1"
          }
        }
      ],
      editingRecord: {
        original: null,
        copy: null
      }
    }
  },
  methods: {
    onEditModalHide(event) {
      if (event.trigger === "ok") {
        // if OK is pressed, map values back to original object.
        for(let fullKey in this.editingRecord.copy){
          const copyObject = this.editingRecord.copy[fullKey]
          /*
            this uses lodash set funcktion 
            https://www.npmjs.com/package/lodash.set
          */
          set(this.editingRecord.original, fullKey, copyObject.value)
        }
      }
      
      this.editingRecord.original = null
      this.editingRecord.copy = null;
    },
    changeRecord(record) {
      const flatCopy = this.flattenObject(record);
      this.editingRecord.original = record;
      this.editingRecord.copy = flatCopy;

      this.$nextTick(() => {
        this.$bvModal.show('edit-modal')
      })
    },
    flattenObject(ob) {
      var toReturn = {};

      for (var i in ob) {
        if (!ob.hasOwnProperty(i)) continue;

        if ((typeof ob[i]) == 'object' && ob[i] !== null) {
          var flatObject = this.flattenObject(ob[i]);
          for (var x in flatObject) {
            if (!flatObject.hasOwnProperty(x)) continue;
            console.log(x)
            toReturn[i + '.' + x] = {
              key: x,
              value: flatObject[x].value
            };
          }
        } else {
          toReturn[i] = {
              key: i,
              value: ob[i] 
          };
        }
      }
      return toReturn;
    }
  }
});
<link href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="//unpkg.com/bootstrap-vue@2.7.0/dist/bootstrap-vue.min.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<script src="https://unpkg.com/lodash.set@4.3.2/index.js"></script>

<div id="app" class="p-4">
  <table class="table table-bordered">
    <tr v-for="element in data">
      <template v-for="field in element">
        <template v-if="typeof field==='object'">
          <td v-for="nestedObjectValue in field">
            {{nestedObjectValue}}
          </td>
        </template>
      <template v-else>
          <td>
            {{field}}
          </td>
        </template>
      </template>
      <td>
        <button class="btn btn-primary" @click="changeRecord(element)">
          Edit
        </button>
      </td>
    </tr>
  </table>
  <b-modal id="edit-modal" v-if="editingRecord.copy" @hide="onEditModalHide">
    <template v-for="obj in editingRecord.copy">
      <label>{{ obj.key }}</label>
      <input v-model="obj.value"  class="form-control"/>
    </template>
  </b-modal>
</div>

关于javascript - 如何从 vue 对话框/模式中获取用户输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60739932/

相关文章:

javascript - 追加现有的 onClick 值

javascript - 根据项目属性值在数组中查找某些项目的最佳方法是什么?

javascript - Vuetify2 垂直 slider 高度不可配置

javascript - 如何编写我的 javascript 代码以便切换正常工作?

javascript - 如何删除数组内数组的最后一项

javascript php 内部服务器错误 500 随机

laravel - Vuejs3 + laravel 8 在本地工作,但在 prod vuejs 文件中抛出语法错误并且 View 未渲染 Uncaught SyntaxError : 59

javascript - 如何在js文件中加载vue组件

node.js - 如何为 GitHub 上的 NPM 包命名(vuejs 包)

javascript - VueJS 条件排序数据到表