【问题标题】:How to delete nested Firebase data with Vue.js如何使用 Vue.js 删除嵌套的 Firebase 数据
【发布时间】:2020-03-11 20:49:07
【问题描述】:

我正在尝试构建一个允许删除嵌套 Firebase 数据的 Vue.js 组件。我的组件目前如下所示:

<v-flex v-for="user in users" :key="user.id" xs12 md12>
  <v-layout row wrap>
    <v-flex v-for="newUser in user.gallery" :key="newUser.id" xs12 sm6 md3>
      <v-img :src="newUser.image" />
      <v-btn @click="deleteImg(newUser.id)">x</v-btn>
    </v-flex>
  </v-layout>
</v-flex>

此组件使用 v-for 指令首先循环所有返回到 users 数组的 Firebase 项目。第二个 v-for 指令循环遍历名为 gallery 的嵌套 Firebase 数组中的所有图像。删除按钮旨在定位嵌套gallery 数组中每个图像的 id (newUser.id)。这是deleteImg() 方法:

    deleteImg (img) {
      db.collection('users').doc(img).delete()
    }

当我单击deleteImg() 按钮时,我收到以下处理程序错误:

Function CollectionReference.doc() requires its first argument to be of type non-empty string, but it was: undefined

如何调整 deleteImg() 处理程序以根据嵌套数组中的 id 正确定位图像?谢谢!

******修订******

这里是完整代码,是我想要完成的一个更好的示例。基本上,该组件设置为将新输入推送到名为 events 的数组中(在 Firebase 中已作为文档字段存在),然后将 user.events 中的这些数组项返回到屏幕。正如您在下面的屏幕截图中所见,这些输入的项目存储在事件数组中。这些数组项在屏幕上渲染得很好。我正在尝试删除这些数组项,但不确定如何正确定位它们。如何配置deleteInput() 方法来定位这些数组项?

<template>
  <div class="input">
    <input v-model="newInput" />
    <button @click.prevent="addInput()">submit</button>
    <br><br>
    <div v-for="user in users" :key="user.id">
      <div v-for="newUser in user.events" :key="newUser.id">
        <h3>{{ newUser.name }}</h3>
        <button @click="deleteInput(newUser.id)">x</button>
      </div>
    </div>
  </div>
</template>

<script>
import firebase from 'firebase'
import { db } from '@/main'
export default {
  name: 'HelloWorld',
  data: () => ({
    newInput: null,
    users: []
  }),
  mounted () {
    this.getData()
  },
  methods: {
    async getData () {
      let snapshot = await db.collection('users').get()
      const users = []
      snapshot.forEach(doc => {
        let appData = doc.data()
        appData.id = doc.id
        users.push(appData)
      })
      this.users = users
    },
    async addInput () {
      let finalInput = this.newInput
      let querySnapshot = await db.collection('users').where('user_id', '==', firebase.auth().currentUser.uid).get()
        querySnapshot.forEach(function(doc) {
          doc.ref.update({'events': firebase.firestore.FieldValue.arrayUnion({
            'name': finalInput
          })
        })
      })
      this.newInput = ''
      this.getData()
    },
    deleteInput (item) {
      db.collection('users').doc(item).delete()
    }
  }
}
</script>

【问题讨论】:

  • 您能否添加users 数组的示例,例如很少的条目。
  • 您好 Renaud,感谢您的回复。请查看我在原始问题下方添加的示例和屏幕截图的修订版。我添加了 FB 仪表板的屏幕截图以显示数组中的一些条目,现在重命名为“事件”。
  • 查看答案。请注意,不知何故,对于您的“修订”,您现在有两个不同的问题,即使它们是链接的。恕我直言,为了将来的读者清楚起见,问一个新问题可能会更好。

标签: javascript firebase vue.js google-cloud-firestore vuetify.js


【解决方案1】:

您的问题中有两段代码(不知何故是两个相互关联但不同的问题):最初的一段和 REVISION 之后的一段。

让我们首先给出第一个问题的答案:使用 Vue.js 组件代码,您需要有一个 users 数组,如下所示:

  users: [
    {
      id: 1,
      gallery: [
        { id: 11, image: "http://...image1.jpg" },
        { id: 12, image: "http://...image2.jpg" },
        { id: 13, image: "http://...image3.jpg" }
      ]
    },
    {
      id: 2,
      gallery: [
        { id: 21, image: "http://...image1.jpg" },
        { id: 22, image: "http://...image2.jpg" },
        { id: 23, image: "http://...image3.jpg" }
      ]
    }
  ]

这意味着您必须“构造”您的 Firestore 文档,使其返回具有这种格式的数组。


第二题(REVISION副标题后):

您应该使用v-for 的可选第二个参数来获取当前项目的索引,并使用此index 值加上user.id 调用deleteInput(),如下所示:

<div v-for="user in users" :key="user.id">
  <div v-for="(newUser, index) in user.events" :key="newUser.id">
    <h3>{{ newUser.name }}</h3>
    <button @click="deleteInput(user.id, index)">x</button>
  </div>
</div>

那么在deleteInput()你需要

任一

用新的events 数组覆盖user(id == user.id)的events 数组,其中您已删除位置index 处的元素,

对整个对象(事件、电子邮件、姓名等)使用arrayRemove() 方法。

我会选择第一种方法。

请注意,根据您的具体用例,您可能必须在事务中执行此操作,以确保在初始读取和修改之间未修改 events 数组。

【讨论】:

  • @JS_is_awesome18 嗨,你有时间看答案吗?
猜你喜欢
  • 2019-10-01
  • 1970-01-01
  • 2019-12-27
  • 1970-01-01
  • 2021-06-14
  • 2020-08-15
  • 2017-06-25
  • 2023-03-18
  • 2023-03-17
相关资源
最近更新 更多