You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firestore forEach仅渲染单个项目,控制台输出两个项目的问题求助

问题:Firestore查询到两个项目但页面仅渲染一个

我用Firestore开发项目/待办应用,目标是返回所有分配给活跃用户的当前项目。通过console.log(doc.id, doc.data())能看到用户已加入的两个项目,但首页只显示一个,求帮忙排查问题。

我的代码

JavaScript函数

const returnProjects = async () => {
  const list = document.querySelector<HTMLDivElement>('#projectList');
  const projects = query(collectionGroup(db, 'projects'));
  const querySnapshot = await getDocs(projects);
  querySnapshot.forEach((doc) => {
    const deadline = doc.data().Deadline;
    const fireBaseTime = new Date(
      deadline.seconds * 1000 + deadline.nanoseconds / 1000000,
    );
    const formatOptions = {
      format: 'dd MMM  yy', 
    };
    console.log(doc.id, '>', doc.data());
    const newElemement = document.createElement('div');
    if (list) list.appendChild(newElemement).setAttribute('class', 'projectCard');
    const card = document.querySelector<HTMLDivElement>('.projectCard');
    if (card) { card.innerHTML = `
    <h4>${doc.id, doc.data().Name}</h4>
    <p>${fireBaseTime.toLocaleDateString('eng-BE', formatOptions)}</p>
    <span>3</span>
    `; }
  });
};

HTML结构

<main>
  <div id="dashboard" class="dashboard">
    <div class='dashboardUtils'>
      <h3 id="dashboardName"></h3>
      <span id="currentDate"></span>
    </div>
    <button id="editDashboard" class="secondary-button"></button>
  </div>
  <div id='dashboardEdits-form' class="editOpen">
    <form id='dashboardEdits' class='edit-form'>
      <div id='practicalDisplayname'>
        <label for='displayname' class='form-label'>Username</label>
        <input type='text' class='form-input' id="displaynameInput" name='displayname'></input>
      </div>
    </form>
    <button id="confirmEdits" class="secondary-button">Save edits</button>
  </div>
  <div id='amountMessage'>
    <h1 id='amountProjects'></h1>
  </div>
  <div id='projectList'></div>
</main>

问题截图

console.log返回两个项目但页面只渲染一个


解决方案

问题核心出在DOM查询逻辑:
document.querySelector('.projectCard')每次只会选中第一个带有projectCard类的元素。循环第一次执行时,创建第一个卡片并填充内容;循环第二次执行时,又选中了第一个卡片,把它的内容覆盖成第二个项目的信息,而新创建的第二个卡片根本没被填充内容。

修复代码如下:

const returnProjects = async () => {
  const list = document.querySelector<HTMLDivElement>('#projectList');
  const projects = query(collectionGroup(db, 'projects'));
  const querySnapshot = await getDocs(projects);
  querySnapshot.forEach((doc) => {
    const deadline = doc.data().Deadline;
    const fireBaseTime = new Date(
      deadline.seconds * 1000 + deadline.nanoseconds / 1000000,
    );
    const formatOptions = {
      format: 'dd MMM  yy', 
    };
    console.log(doc.id, '>', doc.data());
    // 直接操作新创建的卡片元素,无需二次查询DOM
    const newCard = document.createElement('div');
    newCard.className = 'projectCard';
    // 修正逗号运算符问题:原写法只会显示doc.data().Name,如需同时展示ID可改为${doc.id} - ${doc.data().Name}
    newCard.innerHTML = `
      <h4>${doc.data().Name}</h4>
      <p>${fireBaseTime.toLocaleDateString('eng-BE', formatOptions)}</p>
      <span>3</span>
    `;
    list?.appendChild(newCard);
  });
};

内容的提问来源于stack exchange,提问作者Stef Verniers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 07:45:19