【问题标题】:Display lookup/relational data in a v-data-table with Vue and SQLServer使用 Vue 和 SQLServer 在 v-data-table 中显示查找/关系数据
【发布时间】:2019-10-17 10:04:16
【问题描述】:

我使用 Vue.js、Vuetify(应用程序的客户端)和 Express(应用程序的服务器端)创建了一个 Node 应用程序,数据存储在 SQL Server 数据库(关系数据库)中。

一切都在我的开发机器上启动并运行,客户端、服务器和数据库之间的连接正常。

我只是不知道如何在我正在使用的表格中显示“查找数据/关系数据”。

我的数据库的 3 个表:

所以我想显示 FKAssetMake 和 FKAssetModel 的 AssetMake 和 AssetModel INSTEADName 字段.

这是我在浏览器中的表格截图:

如您所见,显示的是 FK 值而不是名称。

要显示的查找表和数据:

chrome 中的数据对象:

我的 Vue 模板:

<template>
  <div id="app">
    <v-app id="inspire">
      <v-card>
        <v-card-title>
          Asset (Vehicle/Vessel)
          <v-spacer></v-spacer>
          <v-text-field
            v-model="search"
            label="Search"
            append-icon="mdi-card-search-outline"
            single-line
            hide-details
          ></v-text-field>
        </v-card-title>

        <v-data-table dense
        :headers="headers"
        :items="assets"
        :search="search"
        sort-by="Name"
        class="elevation-1"
      >
        <template v-slot:top>
          <v-toolbar flat color="white">
            <v-toolbar-title>{{ tabelHeader }}</v-toolbar-title>

            <v-spacer></v-spacer>
            <v-dialog v-model="dialog" max-width="500px">
              <template v-slot:activator="{ on }">
                <v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn>
              </template>
              <v-card>
                <v-card-title>
                  <span class="headline">{{ formTitle }}</span>
                </v-card-title>

                <v-card-text>
                  <v-container>
                    <v-row>
                      <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.Name" label="Name"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.FKMake" label="Make"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.FKModel" label="Model"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.Registration" label="Registration"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.Description" label="Description"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.Year" label="Year"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.Capacity" label="Capacity"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.isVessel" label="Is Vessel"></v-text-field>
                      </v-col>
                    </v-row>
                  </v-container>
                </v-card-text>

                <v-card-actions>
                  <v-spacer></v-spacer>
                  <v-btn color="blue darken-1" text @click="close">Cancel</v-btn>
                  <v-btn color="blue darken-1" text @click="save">Save</v-btn>
                </v-card-actions>
              </v-card>
            </v-dialog>
          </v-toolbar>
        </template>
        <template v-slot:item.Action="{ item }">
          <v-icon
            small
            class="mr-2"
            @click="editItem(item)"
          >
            edit
          </v-icon>
          <v-icon
            small
            @click="deleteItem(item)"
          >
            delete
          </v-icon>
        </template>
      </v-data-table>
      </v-card>
    </v-app>
  </div>
</template>

脚本部分:

<script>

import appConfig from '../config/appConfig.js'

const baseURL = "http://" + appConfig.server.ip + ":" + appConfig.server.port

export default {
  data: () => ({
    search: '',
    dialog: false,
    tabelHeader: '',
    assets: [],
    headers: [
      { text: 'Name', value: 'Name'},
      { text: 'Make', value: 'FKMake'},
      { text: 'Model', value: 'FKModel'},
      { text: 'Registration', value: 'Registration'},
      { text: 'Description', value: 'Description' },
      { text: 'Year', value: 'Year' },
      { text: 'Capacity', value: 'Capacity' },
      { text: 'Vessel', value: 'IsVessel' },
      { text: 'Actions', value: 'Action', sortable: false }
      ],

    editedIndex: -1,
    editedItem: {
      Name: '',
      FKMake: -1,
      FKModel: -1,
      Registration: null,
      Year: null,
      Capacity: null,
      Description: '',
      IsVessel: null
    },
    defaultItem: {
      Name: '',
      FKMake: -1,
      FKModel: -1,
      Registration: null,
      Year: null,
      Capacity: null,
      Description: '',
      IsVessel: null
    }
  }),

  watch: {
    dialog (val) {
      val || this.close()
    },
  },

  methods:{
    editItem (item) {
      this.editedIndex = this.assets.indexOf(item)
      this.editedItem = Object.assign({}, item)
      this.dialog = true
    },

    deleteItem (item) {
      const index = this.assets.indexOf(item)
      var isDelete = confirm('Are you sure you want to delete this item?')

      if (isDelete) {
        this.deleteAssetMake(item, index)
      }
    },

    close () {
      this.dialog = false
      setTimeout(() => {
        this.editedItem = Object.assign({}, this.defaultItem)
        this.editedIndex = -1
      }, 300)
    },

    save () {
      if (this.editedIndex > -1) {
        Object.assign(this.assets[this.editedIndex], this.editedItem)
        this.updateAssetMake(this.editedItem)
      } 
      else {
        this.assets.push(this.editedItem)
        this.addAssetMake(this.editedItem)
      }
      this.close()
    },



    deleteAssetMake (asset, index) {
      fetch(baseURL + '/api/asset/' + asset.ID, {
        method: 'DELETE'
        })
        .then(() => {
          this.assets.splice(index, 1)
          })
          },

    updateAssetMake (asset) {
      fetch(baseURL + '/api/asset/' + asset.ID, {
        body: JSON.stringify(asset),
        method: 'PUT',
        headers: {
        'Content-Type': 'application/json'
        }
      })
      .then(() => {

      })
    },

    addAssetMake (asset) {
      fetch(baseURL + '/api/asset/', {
        body: JSON.stringify(asset),
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        }
      })
    }
  },

  mounted () {
        fetch(baseURL + '/api/asset')
            .then(response => response.json())
            .then((data) => {
                this.assets = data.resultMessage
                console.log(data.resultMessage)
            })

            //.catch(() => console.log('Can’t access  response. Blocked by browser?'))
    },

    computed: {
    formTitle () {
      return this.editedIndex === -1 ? 'New Item' : 'Edit Item'
    },
  }
}
</script>
  1. 如何显示引用表的名称字段而不是外键。

  2. 有没有一种“更好”的方式来完成使用“web 类型”数据库设计的任务?

【问题讨论】:

  • 您的 json 对象中有来自 AssetMake/AssetModel 的数据吗?根据您的屏幕截图,您似乎没有那个
  • 您需要重构您的 sql 查询以将列值包含为assetMake 和assetModel
  • @isebarn 我没有在查询中选择 AssetMake/AssetModel 的数据。如果我确实包含数据,我将如何在代码中设置关系?
  • @chans 我可以这样做来显示文本,但是当它开始编辑或添加时,我将如何为用户提供选项(查找)?
  • @LouwrensPotgieter 检查下面的答案,我列出了需要在 html 和 css 中完成的更改。让我知道这是否能解决您的问题

标签: sql node.js sql-server vue.js vuetify.js


【解决方案1】:

确保您的 api 响应对象应具有 AssetMake 和 AssetModel 属性,然后对 html 和 css 进行以下更改。然后它将按预期工作

    <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.AssetMake" label="Make"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">
                        <v-text-field v-model="editedItem.AssetModel" label="Model"></v-text-field>
                      </v-col>
                      <v-col cols="12" sm="6" md="4">      


{ text: 'Name', value: 'Name'},
      { text: 'Make', value: 'AssetMake'},
      { text: 'Model', value: 'AssetModel'},
      { text: 'Registration', value: 'Registration'},
      { text: 'Description', value: 'Description' },
      { text: 'Year', value: 'Year' },
      { text: 'Capacity', value: 'Capacity' },
      { text: 'Vessel', value: 'IsVessel' },
      { text: 'Actions', value: 'Action', sortable: false }
      ],

    editedIndex: -1,
    editedItem: {
      Name: '',
      AssetMake: '',
      AssetModel: '',
      Registration: null,
      Year: null,
      Capacity: null,
      Description: '',
      IsVessel: null
    },
    defaultItem: {
      Name: '',
      AssetMake: '',
      AssetModel: '',
      Registration: null,
      Year: null,
      Capacity: null,
      Description: '',
      IsVessel: null
    }

【讨论】:

    【解决方案2】:

    @chans 的回答让我走上了正轨。

    由于用户不会“在线”编辑表中的数据,因此可以更改查询以显示所需的数据(AssetMake.Name 和 AsseteModel.Name)。

    我正在使用带有表单的对话框来编辑和添加资产。然后我使用 v-select 来显示查找数据,如下所示:

    <v-col cols="12" sm="6" md="4">
      <v-select v-model="editedItem.FKModel" :items="assetModels" item-text="Name" item-value="ID" label="Model" autocomplete></v-select>
    </v-col>
    

    assetModels 包含所有资产模型,并在挂载事件时从数据库中获取。

    感谢所有参与的人。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-06
      • 2020-04-09
      • 2020-03-26
      • 1970-01-01
      • 2020-08-20
      • 2020-06-10
      • 2020-01-07
      相关资源
      最近更新 更多