vue.js和firebase查询给出错误的数组计数

时间:2019-03-30 02:38:33

标签: javascript firebase vue.js

正在发生奇怪的事情。我正在使用Vue.js和Firebase。我的查询很简单。我的数据库中有3个文档

let tagRef = db.collection('tags')
        tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
        tagRef.onSnapshot(snapshot => {
            this.tags = []
            snapshot.docChanges().forEach(change => {
                let docs = change.doc
                this.tags.push(docs.data())
                console.log(this.tags.length)
            })
        })
如您所见,

我正在将阵列长度记录到控制台。当我刷新页面时,我的控制台日志显示为1 1 2,但是当进行更改时,其显示为正确的1 2 3

我不确定为什么要这样做。

当我将console.log从this.tags.length更改为this.tags时,这些都是我所得到的屏幕截图。

页面刷新

enter image description here

发生更改时

enter image description here

非常感谢您的帮助。

更新:

这是一个游戏。玩家可以互相标记。当玩家被标记时,他们会暂时被禁用,直到他们的标记完成为止。第二件是每位球员的标签不能超过3次。

在created()挂钩中,我查询标签,并且使用了firebase的实时部分,因此,只要标签数据库发生任何更改,代码都会更新。

我有一种如下所示的方法:

countTags(team) {
            return this.tags.filter(function (tag) {
                if(tag.tagged == team.team_id){
                    return team
                }
            })
        },

该方法应根据小组ID返回标签。我的html我有这个

:class="{'taglimit' : countTags(team).length >= 3}" 

如果计数为3或更大,它将添加“ taglimit”类。

第二次更新:

当我在创建的挂钩中运行此查询时,我遇到了问题

let tagRef = db.collection('tags')
    tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
    tagRef.onSnapshot(snapshot => {
        this.tags = []
        snapshot.docChanges().forEach(change => {
            let docs = change.doc
            this.tags.push(docs.data())
        })
    })

但是当我运行此查询时我不会

let tagRef = db.collection('tags')
        tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
        tagRef.get().then((snapshot) => {
            snapshot.forEach(doc => {
                let tag = doc.data()
                tag.id = doc.id
                this.tags.push(tag)
            })
        }).catch(err => {
            console.log(err)
        })

问题是每次标签数据库更改时我都需要更新代码。

第三次更新

我想我找到了问题。我将this.tags = []移到了查询之外,现在一切似乎都正常了。所以现在查询看起来像这样。

this.tags = []
let tagRef = db.collection('tags')
    tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
    tagRef.onSnapshot(snapshot => {
        snapshot.docChanges().forEach(change => {
            let docs = change.doc
            this.tags.push(docs.data())
            console.log(this.tags.length)
        })
    })

第四次更新:

这是HTML

<v-dialog v-model="dialog" persistent transition="scale-transition" fullscreen light>
            <v-btn
            slot="activator"
            fixed
            dark
            fab
            bottom
            right
            color="blue-grey darken-2"
            class="pulse-button"
            >
            <v-icon>directions_run</v-icon>
            </v-btn>
            <v-card color="rgba(224, 224, 224, .95)">
                <v-container grid-list-md text-xs-center>
                    <v-layout row wrap class="tagform-container">
                        <v-btn dark fab right absolute small color="grey darken-3"  @click="dialog = false"><v-icon>close</v-icon></v-btn>
                        <v-layout justify-center>
                            <v-card-title class="display-2 font-weight-black">TAG!</v-card-title>
                        </v-layout>
                        <v-card-text class="subheading">Select a team you want to tag. Note, you only have one tag per game. Use it wisely!</v-card-text>
                        <v-flex xs4 class="add-flex" v-for="team in activeTeams" :key="team.id" >
                            <div class="tag-card" 
                                :class="{'disabled' : activeTag(team).length > 0, 'taglimit' : countTags(team).length >= 3}" 
                                height="100%" 
                                color="white" 
                                style="background:#fff;" 
                                @click="activeTag(team).length > 0 || countTags(team).length >= 3 ? '' : selectedTeam(team)"
                                >
                                <v-layout justify-center>
                                    <v-card-title class="title">{{team.team_name}}</v-card-title>
                                </v-layout>
                                <v-responsive>
                                    <img class="avatar" v-bind:src="team.url">
                                </v-responsive>
                                <v-flex>
                                    <v-card-text class="body-2 text-uppercase">Tap to select</v-card-text>
                                </v-flex>
                            </div>
                        </v-flex>
                    </v-layout>
                </v-container>
            </v-card>
        </v-dialog>

还有更多,但这是最重要的部分。

还有更多代码

data() {
        return {
            feedback: null,
            teams: [],
            taggedteam: null,
            dialog: false,
            stepper: false,
            emojiinput: '',
            search: '',
            e1: 1,
            tag: null,
            tags: [],
            completedtags: [],
            tagstates: []
        }
    },
computed: {
        activeTeams: function () {
            let thisTeam = this.$store.getters.player.team_id
            return this.teams.filter(function (team) {
                if(team.team_id !== thisTeam)
                    return team
            })
        }
    },

其中一种方法:

countTags(team) {
            return this.tags.filter(function (tag) {
                if(tag.tagged == team.team_id){
                    return team
                }
            })
        },

最终创建的钩子

created(){
        // get teams
        let teamRef = db.collection('teams')
        teamRef = teamRef.where('gid', '==', this.$store.getters.gid)
        teamRef = teamRef.orderBy('team_id')
        teamRef.onSnapshot(snapshot => {
            snapshot.docChanges().forEach(change => {
                if(change.type == 'added') {
                    let docs = change.doc

                    let leaderRef = db.collection('leaderboard')
                    leaderRef = leaderRef.where('gid', '==', this.$store.getters.gid)
                    leaderRef = leaderRef.where('team', '==', docs.data().team_id)
                    leaderRef = leaderRef.where('missioncomplete', '==', true)
                    leaderRef.onSnapshot(snapshot => {
                        if(snapshot.empty) {
                            // team has not completed the mission so they can still be tagged
                            this.teams.push(docs.data())
                        }
                    })

                }
            })
        })

        // get tags
        this.tags = []
        let tagRef = db.collection('tags')
        tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
        tagRef.onSnapshot(snapshot => {
            snapshot.docChanges().forEach(change => {
                let docs = change.doc
                this.tags.push(docs.data())
            })
        })

        // get tag states
        this.tagstates = []
        let tagStateRef = db.collection('tagstate')
        tagStateRef = tagStateRef.where('gid', '==', this.$store.getters.gid)
        tagStateRef = tagStateRef.where('state', '==', true)
        tagStateRef = tagStateRef.orderBy('tag')
        tagStateRef.onSnapshot(snapshot => {
            snapshot.docChanges().forEach(change => {
                let docs = change.doc
                this.tagstates.push(docs.data())
            })
        })

        if(this.$store.getters.player.team_id) {
            // check to see if this player has already tagged someone
            let tagRef = db.collection('tags')
            tagRef = tagRef.where('tagger', '==', this.$store.getters.player.team_id)
            tagRef = tagRef.where('gid', '==', this.$store.getters.gid)
            tagRef.onSnapshot(snapshot => {
                snapshot.docChanges().forEach(change => {
                    let docs = change.doc
                    this.completedtags.push(docs.data())
                })
            })
        }
    }

1 个答案:

答案 0 :(得分:1)

在不了解团队/标签及其各自限制之间的确切关系的情况下,深入研究代码有点困难。

但是我从讨论中了解到,如果查询结果超过3个文档,您想更改DOM元素的类。

您将在下面找到一种可能的方法,该方法显示如何处理类更改(以及必要时如何维护tags对象中的data数组,即对数据库起反应变化)。

<template>
  <div :class="{ taglimit: isTagLimit }">Test</div>
</template>

<script>
const fb = require("../firebaseConfig.js");
export default {
  data() {
    return {
      tags: [],
      isTagLimit: false
    };
  },

  created: function() {
    let tagRef = fb.db.collection("tags");
    tagRef = tagRef.where("gid", "==", this.$store.getters.gid);
    tagRef.onSnapshot(querySnapshot => {
      console.log(querySnapshot.size);
      //The next if is sufficient to activate the taglimit class
      if (querySnapshot.size > 3) {
        this.isTagLimit = true;
      } else {
        this.isTagLimit = false;
      }
      //If you want to update the tags property
      var t = [];
      querySnapshot.forEach(doc => {
        t.push(doc.data());
      });
      this.tags = t;
    });
  }
};
</script>

<style>
.taglimit {
  color: deeppink;
}
</style>

请注意,您可以在查询中侦听“原子”更改,而不用替换整个tags数组,并使用更改来更新数组,请参见https://firebase.google.com/docs/firestore/query-data/listen#view_changes_between_snapshots