Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vue.js/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Firebase:为什么在添加新的子引用之前触发值事件_Firebase_Vue.js_Firebase Realtime Database_Vuejs2 - Fatal编程技术网

Firebase:为什么在添加新的子引用之前触发值事件

Firebase:为什么在添加新的子引用之前触发值事件,firebase,vue.js,firebase-realtime-database,vuejs2,Firebase,Vue.js,Firebase Realtime Database,Vuejs2,下面的代码是一个非常简单的Firebase-VueJS应用程序() app.vue <template> <div class="container"> <!-- Adding Quote --> <add-quote/> <!-- Display Quotes --> <quote-list/> </div> </template> <script&

下面的代码是一个非常简单的Firebase-VueJS应用程序()

app.vue

<template>
  <div class="container">
    <!-- Adding Quote -->
    <add-quote/>

    <!-- Display Quotes -->
    <quote-list/>
  </div>
</template>

<script>
import addQuote from "./components/AddQuote.vue";
import quoteList from "./components/QuoteList.vue";

export default {
  components: {
    addQuote,
    quoteList
  },
  methods: {
    get_allQuotes: function() {
      // var vm = this;
      var localArr = [];
      quotesRef
        .once("value", function(snapshot) {
          snapshot.forEach(function(snap) {
            localArr.push({
              key: snap.key,
              category: snap.val().category,
              quoteTxt: snap.val().quoteTxt
            });
          });
        })
        .then(data => {
          this.$store.commit("set_allQuotes", localArr);
        });
    }
  },
  mounted() {
    this.get_allQuotes();
    console.log("App: mounted fired");
  }
};
</script>
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export const store = new Vuex.Store({
    state: {
        quotesList: []
    },
    getters: {
        get_quotesList(state) {
            return state.quotesList;
        }
    },
    mutations: {
        set_allQuotes(state, value) {
            state.quotesList = value;
        }
    }
});

<template>     
    <div class="row quote-edit-wrapper">         
        <div class="col-xs-6">           
            <textarea v-model.lazy="newQuoteTxt" 
                rows="4" 
                cols="50"></textarea>
            <button @click="addQuote">Add Quote</button>
        </div>
    </div>
</template>

<script>

export default {   
  data() {
    return {
            newQuoteTxt: '',
      }
    },
    computed: {
    allQuotes() {
      return this.$store.getters.get_quotesList;
        },
        newQuoteIdx() {
            var localArr = [...this.allQuotes]

            if(localArr.length > 0) {
                var highestKEY, currKEY

                localArr.forEach((element, idx) => {
                    currKEY = parseInt(element.key)
                    if(idx == 0) {
                        highestKEY = currKEY
                    } else {
                        if(highestKEY < currKEY) {
                            highestKEY = currKEY
                        }
                    }
                })
                return highestKEY + 1
            } else {
                return 1
            }
        }
    },
  methods: {
        // ADD new Quote in DB
    addQuote: function() {
            var vm = this
            var localArr = [...this.allQuotes]

            //1. First attach 'value' event listener,
            // Snapshot will contain data from that ref 
            // when any child node is added/updated/delete
            quotesRef.on('value', function (snapshot) {
                snapshot.forEach(function(snap) {
                var itemExists = localArr.some(function (item, idx) {
                        return item.key == snap.key
                    })
                // If newly added item doesn't yet exists then add to local array
                if (!(itemExists)) {
                    localArr.push({
                        key: snap.key,
                        category: snap.val().category,
                        quoteTxt: snap.val().quoteTxt })

                    vm.$store.commit('set_allQuotes', localArr)
                    }
                })
            })

            //2. Second set/create a new quotes in Firebase, 
            // When this quote gets added in Firebase,
            // value event (attached earlier) gets fired  
            //  with 
            var newQuoteRef = quotesRef.child(this.newQuoteIdx)
            newQuoteRef.set({
                category: 'motivation',
                quoteTxt: this.newQuoteTxt
            })
        }
    }
}
</script>
<template>
    <div class="row">
        <div class="col-xs-12 quotes-list-wrapper">
            <template v-for="(quote,idx) in allQuotes">

                <!-- Quote block -->
                    <div class="quote-block-item">
                        <p class="quote-txt"> {{quote.quoteTxt}} </p>
                    </div>
            </template>
        </div>
    </div>  
</template>

<script>
    export default {
        computed: {
            allQuotes() {
                return this.$store.getters.get_quotesList;
            }
        }
    }

</script>

AddQuote.vue

<template>
  <div class="container">
    <!-- Adding Quote -->
    <add-quote/>

    <!-- Display Quotes -->
    <quote-list/>
  </div>
</template>

<script>
import addQuote from "./components/AddQuote.vue";
import quoteList from "./components/QuoteList.vue";

export default {
  components: {
    addQuote,
    quoteList
  },
  methods: {
    get_allQuotes: function() {
      // var vm = this;
      var localArr = [];
      quotesRef
        .once("value", function(snapshot) {
          snapshot.forEach(function(snap) {
            localArr.push({
              key: snap.key,
              category: snap.val().category,
              quoteTxt: snap.val().quoteTxt
            });
          });
        })
        .then(data => {
          this.$store.commit("set_allQuotes", localArr);
        });
    }
  },
  mounted() {
    this.get_allQuotes();
    console.log("App: mounted fired");
  }
};
</script>
import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export const store = new Vuex.Store({
    state: {
        quotesList: []
    },
    getters: {
        get_quotesList(state) {
            return state.quotesList;
        }
    },
    mutations: {
        set_allQuotes(state, value) {
            state.quotesList = value;
        }
    }
});

<template>     
    <div class="row quote-edit-wrapper">         
        <div class="col-xs-6">           
            <textarea v-model.lazy="newQuoteTxt" 
                rows="4" 
                cols="50"></textarea>
            <button @click="addQuote">Add Quote</button>
        </div>
    </div>
</template>

<script>

export default {   
  data() {
    return {
            newQuoteTxt: '',
      }
    },
    computed: {
    allQuotes() {
      return this.$store.getters.get_quotesList;
        },
        newQuoteIdx() {
            var localArr = [...this.allQuotes]

            if(localArr.length > 0) {
                var highestKEY, currKEY

                localArr.forEach((element, idx) => {
                    currKEY = parseInt(element.key)
                    if(idx == 0) {
                        highestKEY = currKEY
                    } else {
                        if(highestKEY < currKEY) {
                            highestKEY = currKEY
                        }
                    }
                })
                return highestKEY + 1
            } else {
                return 1
            }
        }
    },
  methods: {
        // ADD new Quote in DB
    addQuote: function() {
            var vm = this
            var localArr = [...this.allQuotes]

            //1. First attach 'value' event listener,
            // Snapshot will contain data from that ref 
            // when any child node is added/updated/delete
            quotesRef.on('value', function (snapshot) {
                snapshot.forEach(function(snap) {
                var itemExists = localArr.some(function (item, idx) {
                        return item.key == snap.key
                    })
                // If newly added item doesn't yet exists then add to local array
                if (!(itemExists)) {
                    localArr.push({
                        key: snap.key,
                        category: snap.val().category,
                        quoteTxt: snap.val().quoteTxt })

                    vm.$store.commit('set_allQuotes', localArr)
                    }
                })
            })

            //2. Second set/create a new quotes in Firebase, 
            // When this quote gets added in Firebase,
            // value event (attached earlier) gets fired  
            //  with 
            var newQuoteRef = quotesRef.child(this.newQuoteIdx)
            newQuoteRef.set({
                category: 'motivation',
                quoteTxt: this.newQuoteTxt
            })
        }
    }
}
</script>
<template>
    <div class="row">
        <div class="col-xs-12 quotes-list-wrapper">
            <template v-for="(quote,idx) in allQuotes">

                <!-- Quote block -->
                    <div class="quote-block-item">
                        <p class="quote-txt"> {{quote.quoteTxt}} </p>
                    </div>
            </template>
        </div>
    </div>  
</template>

<script>
    export default {
        computed: {
            allQuotes() {
                return this.$store.getters.get_quotesList;
            }
        }
    }

</script>

  • 接下来,使用ID
    this.newQuoteIdx

    var newQuoteRef=quotesRef.child(this.newQuoteIdx)

  • 然后调用
    set()
    (在这个新创建的Ref上)将newquote添加到firebase实时数据库

  • value
    事件被触发(从步骤1附加)并调用侦听器/回调 回调通过匹配localArr键和
    snap.key
    ,在现有项目列表中查找此新报价的键,如果未找到,则将新报价添加到localArr。localArr提交到vuex存储

    `vm.$store.commit('set_allQuotes', localArr)`
    
    VueX然后更新此阵列的所有订阅服务器组件。VueJS然后将新的引号添加到现有的引号列表中(更新DOM)

    在调试
    addQuote
    方法时,我注意到的问题是,脚本的执行/流(通过chrome调试器中的F8)首先进入附加到
    value
    事件的侦听器/回调,然后是添加新quote(在firebase上)的code
    newQuoteRef.set({…})
    ,这反过来会导致触发“值”事件

    我不知道为什么会发生这种情况。任何人都可以解释为什么在创建引号之前调用侦听器/回调

    是(QuotesRef的)子节点缓存在客户端,以便在添加新quote之前激发“value”


    谢谢

    如果我正确理解了你的问题(你的代码不是很容易理解!:-),这是正常的行为。正如报告中所述:

    值事件将触发一次,初始数据存储在 此位置,然后每次输入数据时再次触发 更改

    您的沙盒演示实际上并没有显示应用程序是如何工作的,但通常您不应该在将新节点保存到数据库的方法中设置侦听器。这两件事应该解耦

    一种常见的方法是在组件的
    创建的
    钩子(请参见和)中设置侦听器,然后在
    addQuote
    方法中写入数据库。你一写,听众就会被解雇