我一遍又一遍地阅读Firebase文档,只需要澄清一下。对于我的具体代码,这不是我对Firebase的一般理解。
我知道var words = document.querySelectorAll('.word');
var numbers = document.querySelectorAll('.number');
var selectedWordIndex;
var selectedNumberIndex;
var timerInstance;
// Validate game settings
if (words.length !== numbers.length) {
return console.error('Words list size should be same as numbers list');
}
// Register click event handlers on all words and numbers
for (var i = 0; i < words.length; i++) {
words[i].setAttribute('data-index', i);
words[i].addEventListener('click', function(event) {
selectedWordIndex = this.dataset.index;
checkMatching();
});
}
for (var i = 0; i < numbers.length; i++) {
numbers[i].setAttribute('data-index', i);
numbers[i].addEventListener('click', function(event) {
selectedNumberIndex = this.dataset.index;
checkMatching();
});
}
function checkMatching() {
// When user selection matches
if (selectedWordIndex === selectedNumberIndex) {
// Remove pair
var word = document.querySelector('.word[data-index="' + selectedWordIndex + '"]')
var number = document.querySelector('.number[data-index="' + selectedNumberIndex + '"]')
word.parentNode.removeChild(word);
number.parentNode.removeChild(number);
// Reset selection
selectedWordIndex = null;
selectedNumberIndex = null;
// Check if game is ended
if (document.querySelectorAll('.word').length === 0) {
// Remove blocks and stop the timer
var words = document.querySelector('.words');
var numbers = document.querySelector('.numbers');
words.parentNode.removeChild(words);
numbers.parentNode.removeChild(numbers);
clearInterval(timerInstance);
}
} else if (selectedWordIndex && selectedNumberIndex) {
// Register an error while selection does not match
var errorCounter = document.querySelector('.errors .counter');
errorCounter.innerHTML = parseInt(errorCounter.innerHTML, 10) + 1;
}
}
function startTimer() {
var display = document.querySelector('.time');
var timer = 0, minutes, seconds;
timerInstance = setInterval(function () {
minutes = parseInt(timer / 60, 10);
seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes;
seconds = seconds < 10 ? "0" + seconds : seconds;
display.innerHTML = minutes + ":" + seconds;
timer++;
}, 1000);
}
startTimer();
每次调用时都会检索所有数据,并继续监视数据库的变化。 .Value
查找引用子项的更改。 .ChildAdded
最初还会检索所有值吗?我是否应该为同一路径同时实施.ChildAdded
和.Value
?如果没有,当我尝试执行.ChildAdded
时,没有任何显示,但是当我运行.ChildAdded
时,我的所有项目都会显示出来。我不想要的是每次更改或添加单个值时都要从数据库中重新获取每个值,因为当我有数千个要获取的项目时,这似乎会导致一些带宽问题。最好的工作流程是使用ObserveSingleEventOfType创建.Value函数(.Value
),这样它只调用一次,然后有一个重复的函数(getAllItems()
),除了getNewItems()
和observeEventOfType?< / p>
答案 0 :(得分:2)
如果你有这个节点
node:{
data1:"data",
data2:{
subdata1:1,
subdata2:2
}
}
第一次调用带有Value
的{p> observeEventOfType
+每次"node"
内的内容发生变化时Value
只会调用observeSingleEventOfType
1} p>
带有observeEventOfType的 Child_Added
将被调用两次["data1"
(它将包含字符串&#34; data&#34;和"data2"
(它将包含一个带有子项的对象{ {1}}和"subdata1"
&#34;]
"subdata2
或Child_Changed
更改时,observeEventOfType
都会调用<"data1"
"data2"
{每次"data2"
时都会调用"subdata1"
中的事件"subdata2"
或"subdata3"
更改,或插入"data1"
)
这可以组合使用,但它取决于每种情况......
对于事件类型:
通常当您指向Value
之类的最终节点时,使用"data2"
,当您在具有类似child_added
类似节点列表的节点中时,使用组合child_changed
,child_removed
和struct
对于观察员类型:
如果你想在特定时刻获得价值,那么它是直截了当的;你使用&#34;单一事件观察者&#34;。如果您想随时关注价值,请使用&#34;事件观察员&#34;