【问题标题】:How to take userinput from vue dialog/modal如何从 vue 对话框/模态中获取用户输入
【发布时间】:2020-03-18 12:46:52
【问题描述】:

我有一个 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>

点击按钮的结果是这个对话框:

https://imgur.com/4aOEjde

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

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

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

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    这是完成您正在寻找的事情的一种方法。

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

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

    此解决方案使用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>

    【讨论】:

    • 哇,非常感谢!我现在正在尝试将其应用于我的项目。呃,我也可以使用 vue-lodash 吗? npmjs.com/package/vue-lodash lodash.set 只是 vue-lodash 的一部分吗?如果没有,我该如何在安装后集成 lodash.set?您链接上的“文档”只是说: var set = require('lodash.set');但是我在哪里做呢?这真的足够了吗? xD
    • 我不知道vue-lodash 是否包含 set 方法(可能包含),但如果您只需要 lodash.set 则无需导入很多其他内容。首先运行npm install lodash.set,然后在组件的&lt;script&gt; 标记顶部添加import set from 'lodash.set'
    • 天哪,谢谢,我的项目中运行了你的代码! :=) 我现在将尝试将您的方法整合到我的网站中,或者用您的方法替换我的方法 ^^ 天哪,太好了,谢谢! :D 如果我遇到任何进一步的问题,我会接受您的回答,也许会在 cmets 中回复您! :) 你真的拯救了我的一天! :D
    • 整齐地集成到我的代码中,谢谢! :) 我仍在尝试理解代码的某些部分。 “flattenObject”中的for循环有“if (!ob.hasOwnProperty(i)) continue;”我试图找出何时满足条件,但似乎从未满足。将控制台日志放入其中,console.log 从未触发,因此从未输入分支,无论是您的数据还是我的数据。此外,ob 是一个 vue 可观察对象,它具有大量与循环无关的属性。这是默认的 vue 或 JS 行为,它“忽略”了这些属性,只循环相关数据?
    • @baryon123 我从this answer 得到了那个特定的代码 - 这是一个检查属性是否被继承的检查。如果它是继承的,它将被跳过。你可以阅读更多关于 hasOwnProperty here
    猜你喜欢
    • 2013-02-27
    • 2012-02-10
    • 2011-12-12
    • 2011-02-24
    • 2015-06-22
    • 2021-10-30
    • 2012-05-10
    • 2016-07-07
    • 1970-01-01
    相关资源
    最近更新 更多