【问题标题】:How to calculate table column in JavaScript?如何在 JavaScript 中计算表格列?
【发布时间】:2019-02-22 10:35:12
【问题描述】:

我使用 JavaScript 返回一个商店服务员列表,并在最后一行(服务员)之后动态插入一行,显示总计列下所有服务员的总数。但现在我需要做的是在运行总计列中显示每个服务员的运行总计。

这就是我要显示的内容,显然运行总计公式不在这里......

我知道有一种更 Angular-y 的方式来做到这一点。我肯定会实施这种方式。但是现在,我只想让你专注于我正在走的路,关于计算这个运行的总列。以下是我希望您关注的具体内容:

var total = 0;
  document.querySelectorAll("td:nth-child(4)").forEach((cell, index) => {
    this.attendantNames.forEach(a=>{
      this.total += a.total;
    });
    cell.innerText = this.total;
  });

但如果你需要查看整个控制器代码,就在这里:

export default class StoreTotalsController {
  constructor() {
    this.attendantNames = [];
    this.stores = [];
    this.emptyResult = true;
    this.totals = 0;
    this.total = 0;
    this.cellValue = "";
    this.runningTotalCells;
    //this.previousTotal = 0;
  }

  getAttendants() {
    showLoader('Searching');
    const baseUrl = '/src/areas/store-totals/services/tender-total-data.json';
    const getStores = new Request(baseUrl, {
      method: 'GET'
      });
    fetch(getStores).then(function(response){
      return response.json();
    }).then(resp => {
    if (!(resp[0] && resp[0].error)) {
      this.attendantNames = resp.stores[0].attendants;
      this.attendantNames.forEach(a=>{
        this.totals += a.total;
        console.log("Attendant :" , a.attendantName, "Had a total of :" , a.total, "With running total " , this.totals);
      });

      //Row at bottom displaying total of totals
      var table = document.querySelector('.table');
      var td1 = document.createElement('td');
      var td2 = document.createElement('td');
      var td3 = document.createElement('td');
      var tr = document.createElement("tr");
      tr.setAttribute("class", "last-row");
      var td1Data = document.createTextNode('  ');
      var td2Data = document.createTextNode('Total');
      var td3Data = document.createTextNode('$' + this.totals.toFixed(2));
      td1.appendChild(td1Data);
      td2.appendChild(td2Data);
      td3.appendChild(td3Data);
      tr.appendChild(td1);
      tr.appendChild(td2);
      tr.appendChild(td3);
      table.appendChild(tr);

      this.emptyResult = false;
      this.errorMessage = null;

    } else {
      this.errorMessage = resp[0].error.name;
    }
    digest();

  var total = 0;
  document.querySelectorAll("td:nth-child(4)").forEach((cell, index) => {
    this.attendantNames.forEach(a=>{
      this.total += a.total;
    });
    cell.innerText = this.total;
  });
    showLoader(false);
    });
  }

  searchIfReady() {
    if (this.search && this.date && this.date.isValid()) {
      this.getSearch();
    }
  }

  updateDate(date) {
    this.date = moment(date).startOf('day');
    this.searchIfReady();
  }
}
StoreTotalsController.$inject = ['$stateParams'];

【问题讨论】:

    标签: javascript angularjs json html-table


    【解决方案1】:
    let total = 0;
    
    document.addEventListener("DOMContentLoaded", function(event) { 
      document.querySelectorAll("td:nth-child(2)").forEach((cell, index) => {
        const cellInnerHTML = cell.innerHTML
        const numericTotal = cellInnerHTML.substring(1, cellInnerHTML.length);
    
        total += parseInt(numericTotal) * 1000;
    
        cell.parentElement.querySelectorAll("td")[2].innerHTML = total;
      });
    });
    

    代码笔:

    https://codepen.io/anon/pen/vzQyGy

    1. 您需要注意删除$ 符号。
    2. 在 parseInt 之后,由于您的数字格式,您将留下(根据您的示例)2、8 和 5,而不是 2000、8000、5000。 我天真地乘以 1000。应该找到更好的解决方案,这只是一个草图。
    3. 您需要将数字格式化回您想要的格式。

    解决方案就在那里,我把细节留给你:)

    如果你的代码应该是这样的:

    this.attendantNames.forEach((attendant, index) => {
        const table = document.querySelector('.table');
        const attendantRow = table.querySelectorAll('tr')[index];
        const runningTotalCell = attendantRow.querySelectorAll('td')[2];
    
        //am assuming that this.totals is 0 at the beginning of this loop, right?
        this.totals += parseInt(attendant.total); //am not sure of format attendant.total have in your data, not sure if you need parsing here and if  it will work
    
        runningTotalCell.innerHTML = `$${this.totals.toFixed(2)}`; 
    })
    

    应该可以工作,但不能运行代码,看看它是否真的发生或抛出错误,调试它等等。我不能给你 100%。 如果有任何错误,请尝试自己解决:) 如果你会卡住,回来问我哪里出了问题,我会再次尝试帮助:)

    一般评论

    • 你的方法被命名为getAttendants,它的作用远不止于此(得到服务员)。它获取服务员数据,创建表的一部分,并用数据填充该表。它不应该。方法应该只做一件事(单一职责原则)并正确命名。
    • 您应该在几个函数之间划分职责并在它们之间传递数据,让每个函数只处理一项任务

    例如。 - 功能 A - 获取话务员数据 - 函数 B - 创建表 - 函数 C - 用服务员数据填充该表

    在这些函数中,您可以将代码拆分为更小的函数。 在您放置 cmets 的地方,您可以使用其中包含注释代码的函数,并且仅按名称,它们将向开发人员解释他们的工作。 前任。

    以下三行用于每个循环,仅用于访问该 runnintTotalCell。

    const table = document.querySelector('.table');
    const attendantRow = table.querySelectorAll('tr')[index];
    const runningTotalCell = attendantRow.querySelectorAll('td')[2];
    

    您可以提取它们并用单独的函数包装:

    getRunningTotalCellForRow(rowIndex) { 
        const table = document.querySelector('.table');
        const attendantRow = table.querySelectorAll('tr')[index];
        return attendantRow.querySelectorAll('td')[2];
    }
    

    并在 forEach 循环中使用。

    等等

    一般来说,要学习正确的编码方法,您可以学习一些教程,阅读一些书籍并了解规则:)

    至于书籍 - Robert C. Martin 的 Clean Code 是经典书籍之一。 至于教程和其他在线资源。

    在浏览器中搜索您选择的文本,例如: - 如何编写干净的代码 - 单一责任原则 - 干吻固体 - 关键软件开发原则

    我认为从您会发现的网站中,您可以找到更多并深入了解它。

    祝你好运,玩得开心!

    编辑代码后:

    我检查了你的截图。红色部分告诉我,在第一行中,您在第二个单元格中插入 TOTAL FOR ALL(大约 32k),它是该值,但在第三个值乘以三时翻了一番。这导致了结论,你必须在你的循环中弄乱了一些添加。

    所以

    var total = 0;
    document.querySelectorAll("td:nth-child(4)").forEach((cell, index) => {
      this.attendantNames.forEach(a=>{
        this.total += a.total;
      });
      cell.innerText = this.total;
    });
    

    你在上面做什么:

    1. 你定义了 var total = 0(并且从不使用它)

    2. 对于每个第 4 个单元格

    3. 带走所有服务员并为每个服务员

    4. 将其total 值添加到this.total

    5. 并将其插入innerText

    你现在看到了吗?对于每个单元格,您将插入所有服务员的汇总总计(加上您已经拥有的 this.totals 值,因为您永远不会将其归零)。

    以下正确版本:

    const runningTotalCells = document.querySelectorAll("td:nth-child(4)");
    //no need for nested loops
    this.attendantNames.forEach((attendant, index) => {
      this.total += a.total;
      runningTotalCells[index].innerText = this.total;
    })
    

    现在可以用了吗?

    【讨论】:

    • 你能把那个函数放在我的函数的上下文中吗?我的意思是编辑您的答案以包含整个 getAttendants() 函数。我会很感激的。
    • @CMazz 请立即尝试。我只处理了forEach 循环,它应该替换你的循环
    • 谢谢。我已经编辑了我的帖子。如果你有时间,也许你可以看看。再次感谢。
    • 我再次感谢您的 cmets。我很欣赏你通过的洞察力。
    • @CMazz 检查最后一部分,如果我帮助了你,请将其标记为答案:)。所有的部分都在这篇文章中,你只需要小心和准确:) 祝你好运
    【解决方案2】:

    您可以使用$("td:nth-child(2)").each 循环每个第二个单元格,然后将该单元格值添加到总变量中,并使用$(this).next('td').text(total); 将总数打印到下一个 td

    var total = 0;
    $("td:nth-child(2)").each(function( index ) {
      total = parseInt($(this).text()) + parseInt(total);
      $(this).next('td').text(total);
    });
    table{
    text-align: center;
    }
    td{
    width: 100px;
    background-color: orange;
    }
    th{
    background-color: orange;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <table>
    <th>name</th>
    <th>Total</th>
    <th>Running Total</th>
    <tr>
    <td>Eric</td>
    <td>100</td>
    <td></td>
    </tr>
    
    <tr>
    <td>Lars</td>
    <td>20</td>
    <td></td>
    </tr>
    
    <tr>
    <td>Patrick</td>
    <td>200</td>
    <td></td>
    </tr>
    </table>

    【讨论】:

    • 您的答案很漂亮,而且效果明显。但我需要使用纯 JavaScript。
    猜你喜欢
    • 2021-08-05
    • 2017-04-30
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 2022-08-18
    • 2016-11-01
    • 2016-09-11
    • 1970-01-01
    相关资源
    最近更新 更多