繁体   English   中英

如何在动态 javascript 表中显示行数计数?

[英]How do I display the row number count in a dynamic javascript table?

我在前端使用 ejs 遍历数组并在 bootstrap 5 表中显示数据。 该表是动态的,因此行将随时间添加和删除。

所有数据都没有错误地通过并且表格正在填充,但是,我想让第一列显示每一行的“计数”。 例如,“1、2、3、4、5 等”。

我已经尝试使用indexOf但没有成功,并且由于代码已经存在于循环中,创建另一个循环需要我切换我的 ejs 语法并且我失去了计算数组长度的能力。

下面是我的客户端代码,它在每一行的整个#列中产生值-1

 <div class="col-12 d-flex flex-row-reverse">
  <a href="" class="a1" onclick="exportTableToCSV(null, 'text.csv')">Export to csv</a>
 </div>
 <div class="table-responsive">
<table class="table table-hover">
  <thead>
    <tr>
      <th scope="col">#</th>
      <th scope="col">Email</th>
      <th scope="col">Gender</th>
      <th scope="col">Age</th>
      <th scope="col">Clicked IG</th>
      <th scope="col">Date Added</th>
      <th scope="col">Remove</th>
    </tr>
  </thead>
  <tbody>
    <% for (let fan of artist.fans){%>
    <tr>
      <th scope="row"><%= artist.fans.indexOf(fan.id) %></th>
      <td><%= fan.email %></td>
      <td><%= fan.gender %></td>
      <td><%= fan.age %></td>
      <td><%= fan.subscribed %></td>
      <td><%= fan.dateAdded %></td>
      <td style="padding-left: 2rem;">
        <button onclick="removeRow()" ></button>
         </td>
      <td style="padding-left: 2rem;"><i class="bi bi-trash"></i></td>
      <% } %> 
    </tr>
  </tbody>
</table>
</div>

如果我将artist.fans.indexOf(fan.id) fan.id 我会得到每个粉丝对应的 objectId email object。

如果我将artist.fans.indexOf(fan.id)artist.fans.length切换,我会在每一行的#列下得到7

这是我的数据库 model:

const artistSchema = new Schema({
image: [ImageSchema], 
genre: [ String ], 
fans: [{ 
    email: String, 
    subscribed: String, 
    gender: String, 
    age: Number 
        dateAdded: {
            type: Date,
            default: Date.now
                }
      }], 
 });

如何让每一行编号?

问题是你在artist.fans.indexOf(fan.id)中使用了fan.id作为搜索参数,它不能直接访问抛出artist.fans所以你需要使用另一种方法来接受comparing function这样你就可以比较他们的身份证

尝试使用

<th scope="row"><%= artist.fans.findIndex(f=> f.id == fan.id) %></th>

长话短说:

只需这样做:

<% for( const fan of artist.fans.map( ( e, index ) => ({ index, ...e }) ) ) { %>
<tr>
    <th scope="row"><%= fan.index %></th>
    <td><%= fan.email %></td>
    <!-- etc -->
</tr>

<% }%>

解释:

我想让第一列显示每一行的“计数”。 例如,“1、2、3、4、5 等”。

  • 这不是“计数”。 我将其称为“行号”(如果基于 1)或“行索引”(如果基于 0)。

  • 如果您使用 SQL 来获取数据,那么您只需在查询中使用ROW_NUMBER()并将其 map 用于Fan类型中的一些新number属性。

    • 请注意,如果没有明确定义的ORDER BY标准, ROW_NUMBER()值有点毫无意义。
  • 不要在循环中使用indexOfindexOf的运行时复杂度为O(n) ,因此不建议在同一数组的循环中使用 function,因为这会给你O(n^2)运行时,这是非常糟糕的.

    • 这也适用于其他O(n)缩减函数,如findIndexfindincludeslastIndexOf
    • 此外, indexOf (和其他)仅在Array.prototype上定义,因此它不适用于其他类型的可迭代对象,例如NodeList
  • 在 ejs 中, 您可以使用Array.prototype.map的重载,它为您提供每个elementindex ,并将index粘贴到每个element object 中,如下所示:

const fansWithIndex = artist.fans
    .map( function( element, index ) {
        element.index = index;
        return element;
    } );

<% for( const fan of fansWithIndex ) { %>
<tr>
    <th scope="row"><%= fan.index %></th>
    <td><%= fan.email %></td>
    <!-- etc -->
</tr>

<% }%>

...虽然 FP 纯粹主义者(像我自己)会争辩说上面的例子是错误的代码,因为它改变了源数据,而应该使用Object.assign代替。 此外,长格式function可以使用箭头函数=>变得更简单,如下所示:

const fansWithIndex = artist.fans.map( ( e, idx ) => Object.assign( { index: idx }, e ) );

<% for( const fan of fansWithIndex ) { %>
<tr>
    <th scope="row"><%= fan.index %></th>
    <td><%= fan.email %></td>
    <!-- etc -->
</tr>

<% }%>

这可以进一步简化:

const fansWithIndex = artist.fans.map( ( e, index ) => ({ index, ...e }) );

<% for( const fan of fansWithIndex ) { %>
<tr>
    <th scope="row"><%= fan.index %></th>
    <td><%= fan.email %></td>
    <!-- etc -->
</tr>

<% }%>
  • 因为artist.fans.map(...)部分是带有单个 output 的单个表达式,您现在可以将其直接内联到您的for(of)语句中,如下所示:
<% for( const fan of artist.fans.map( ( e, index ) => ({ index, ...e }) ) ) { %>
<tr>
    <th scope="row"><%= fan.index %></th>
    <td><%= fan.email %></td>
    <!-- etc -->
</tr>

<% }%>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM