Firestore数据上的嵌套v-for循环反应性地复制更改的最深层

时间:2018-12-22 16:51:11

标签: firebase vuejs2 google-cloud-firestore vuex

我在firestore中嵌套了数据,我想将其表示为嵌套列表。但是,当我更改Firestore数据库中的值时,第二级值不会更新。

在加载时看起来是正确的: enter image description here

但是,当我将“ Temperature1”更改为“ Temperature”时,它的更新如下: enter image description here

如果我重新加载页面,则所有问题都会再次纠正: enter image description here

如果我更改顶级名称,例如仙人掌,它的行为符合预期(名称会进行动态更新)。

我如何才能使二级字符串也可以简单地进行反应性更新而无需重复?

这是我在firestore中的数据结构:(ID是自动生成的ID)

-users (collection)
|-id0 (doc)
 |-name: "Niels"
 |-tiles (collection)
  |-id1 (doc)
  | |-name: "Monstera Deliciosa"
  | |-services (collection)
  |   |-id2 (doc)
  |   | |-name: "Temperature"
  |   |-id3 (doc)
  |     |-name: "Relative-humidity"
  |-id4 (doc)
    |-name: "Cactus"
    |-services (collection)
      |-id2 (doc)
        |-name: "Soil moisture"

以下是我的代码的摘录:

我的Vue组件(这是主视图):Dashboard.vue

<template>
    <div id="dashboard">
        <ul v-for="tile in tiles" :key=tile.id>
            <li>{{ tile.name }}</li>
            <ul v-for="service in tile.services" :key=service.id>
                <li>{{service.name}}</li>
            </ul>
        </ul>
    </div>
</template>

<script>
    import { mapState } from 'vuex'
    const fb = require('../firebaseConfig.js')

    export default {
        computed: {
            ...mapState(['tiles'])
        }
    }
</script>

还有我的store.js文件:

import Vue from 'vue'
import Vuex from 'vuex'
const fb = require('./firebaseConfig.js')

Vue.use(Vuex)

// handle page reload
fb.auth.onAuthStateChanged(user => {
    if (user) {
        // realtime updates from tiles
        fb.usersCollection.doc(user.uid).collection('tiles').orderBy('name', 'asc').onSnapshot(tilesSnapshot => {
            let tilesArray = []

            tilesSnapshot.forEach(tileDoc => {
                let tile = tileDoc.data()
                tile.id = tileDoc.id
                // console.log("Tile name:", tile.name)

                let servicesArray = []
                tileDoc.ref.collection('services').onSnapshot(servicesSnapshot => {
                    servicesSnapshot.forEach(serviceDoc => {
                        let service = serviceDoc.data()
                        service.id = serviceDoc.id
                        servicesArray.push(service)
                    })
                })
                tile.services = servicesArray
                tilesArray.push(tile)
            })
            store.commit('setTiles', tilesArray)
        })
    }
})

export const store = new Vuex.Store({
    state: {
        tiles: []
    },
    mutations: {
        setTiles(state, val) {
            if (val) {
                state.tiles = val
            } else {
                state.tiles = []
            }
        }
    }
})

1 个答案:

答案 0 :(得分:1)

问题的第一部分(“当我更改Firestore数据库中的值时,第二级值未更新”)来自Firestore读取浅的事实。

您的第一个onSnapshot()监听以下查询的结果:

fb.usersCollection.doc(user.uid).collection('tiles').orderBy('name', 'asc')

查询集合中的文档不会从子集合中提取数据。因此,第一个onSnapshot()会在您更改tiles集合中的文档时触发,但不会在您更改services子集合中的文档时触发。