【问题标题】:Load data from firebase to HTML table将数据从 firebase 加载到 HTML 表
【发布时间】:2021-02-18 13:35:50
【问题描述】:

我有一个 FireBase 实时数据库,其中包含一些我想在 HTML 网格中显示的数据。数据库的结构非常简单:

我想要做的是将“id”、“第一列”、“第二列”、“第三列”作为列标题和来自数据库的数据显示在每个相应的标题下。

这是我的 HTML 部分:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>

<body>

  <!--Firebase SDK code below-->
  <script src="/__/firebase/8.2.6/firebase-app.js"></script>
  <script src="/__/firebase/8.2.6/firebase-analytics.js"></script>
  <script src="/__/firebase/8.2.6/firebase-database.js"></script>

  <!-- Initialize Firebase -->
  <script src="/__/firebase/init.js"></script>

  <script src="firebase.js"></script>

  <button onClick="readData()">Load data from FB</button>

  <table class="table table-striped" id="table">
    <thead>
      <tr>
        <th>ID</th>
        <th>First column</th>
        <th>Second column</th>
        <th>Third column</th>
      </tr>
    </thead>
    <tbody>
</body>

</html>

这里是JS:

// Firebase reference
var database = firebase.database();
rootRef = database.ref('/');
itemsRef = database.ref('/Items/');

// Other vars
var pushLabels = ["id", "First column", "Second column", "Third column"];


function readData() {

  itemsRef.once('value', function (snapshot) {
    var arrayLen = pushLabels.length;
    var childKeyArr = [];

    var table = document.querySelector('#table tbody');

    snapshot.forEach(function (childSnapshot) {

      var childKey = childSnapshot.key;
      childKeyArr.push(childKey);
    });

    for (var i = 0; i < childKeyArr.length; i++) {

      var row = table.insertRow(-1);
      for (var j = 0; j < arrayLen; j++) {
        cell = row.insertCell(-1);
      };
    };

    for (var i = 0; i < childKeyArr.length + 1; i++) {
      database.ref('/Items/' + i).once('value', function (snapshot) {
        snapshot.forEach(function (childSnapshot) {
          var noha = childSnapshot.val();
          for (var i = 0; i < pushLabels.length; i++) {
            cell.innerHTML = noha;
          };
        });
      });
    }
  });
}

我认为它相当“过于复杂”。我能够根据数据库中父项的数量(1、2、3,如数据库层次结构屏幕截图所示)创建行,并且对于每个节点,我都能够将数据检索到快照中,但我不知道如何将其投影到网格中,以便每个值正确显示到它的相关列。 我在代码中放入单元格的部分显然是错误的 - 我只是在测试不同的方式。

任何帮助将不胜感激!此外,如果有任何更好的解决方案,一些可以以更简单的方式做到这一点的库,如果你能推荐,我会很高兴。 谢谢!!

【问题讨论】:

    标签: javascript html firebase firebase-realtime-database


    【解决方案1】:

    是否需要固定数量的列,还是要动态创建列? 您的列标题是否已经在 html 文件中,或者您是否希望从数据库中的键中创建它们?您的 html 文件中有列标题,但您也有一个存储相同内容的数组。它们还匹配每个子项的键,所以看起来有点混乱。

    这是一个快速示例,说明如何获取表格主体、创建新行、创建单元格、添加数据库中的值,然后将行添加到表格主体。

    var itemsRef = firebase.database().ref().child("Items");
    var tableBody = document.querySelector('#table tbody');
    
    function readData() {
        itemsRef.once('value', function (snapshot) {
            snapshot.forEach(function (item_snapshot) {
                //Create html elements, TRs, TD,s etc.
                var row = document.createElement("tr");
                var col1 = document.createElement("td");
                var col2 = document.createElement("td");
                var col3 = document.createElement("td");
                var col4 = document.createElement("td");
                //Add data to the new elements.
                col1.innerText = item_snapshot.key;
                col2.innerText = item_snapshot.child("First column").val();
                col3.innerText = item_snapshot.child("Second_column").val();
                col4.innerText = item_snapshot.child("Third_column").val();
                //Append the cells into the row and the row into the table body.
                row.appendChild(col1);
                row.appendChild(col2);
                row.appendChild(col3);
                row.appendChild(col4);
                tableBody.appendChild(row);
            });
        });
    }
    

    如果我没有误解你的话,这听起来有点像你想让每个子项的键成为列标题,但请记住,每个子项中可能没有相同的节点,你只想加载标题一次,而不是从每个子项加载。

    【讨论】:

    • 您好,列数是固定的,我正在使用 html 文件中所述的标题。很抱歉在这里造成混淆——我已经从其他函数中剥离了代码,以便更清晰地专注于读取部分。我有这个数组主要用于写入数据库,这是我为了这个问题而删除的部分。你是对的 - 键基本上是列标题所以这就是为什么我把它放到 html 中只加载一次。我会检查解决方案,但它看起来不错!我想我把它复杂化了,因为我想迭代这些项目,但这看起来更可行,因为它严格说明了每个值应该去哪里。
    • 嗨 Spectre,所以我已经尝试过了,但我得到了“tableBody.appendChild(row);”的“Uncaught TypeError: Cannot read property 'appendChild' of null”。看起来它试图附加当时不存在的行,考虑到它是在那之前创建的,这有点奇怪。知道这里可能是什么问题吗?提前致谢!
    • 只有在您还没有实际创建行或者您已经有另一个使用名称“行”的变量时才可以为空?另外,我会通过简单地说 document.querySelector('#table tbody').innerText = "testing" 来测试,看看它是否被插入到表体中。可能是您实际上并未从 html 文件中获取表格正文元素。另外,使用与标签名称和类匹配的 ID 是不好的。它变得令人困惑。
    • 实际上,在第二次查看您的 html 文件时,您的“tbody”标签没有结束标签,因此不能在其间添加子标签。添加结束标签,它应该可以工作。
    • 您好,感谢您指出这一点。我对标记做了一些改进(忽略了关闭 tbody),但最终的问题是我无法全局定义表引用,必须在读取函数中定义它。现在它就像一个魅力。感谢您在这里的帮助并花时间查看它!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 1970-01-01
    • 2019-04-25
    • 1970-01-01
    相关资源
    最近更新 更多