[英]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()
值有点毫无意义。 不要在循环中使用indexOf
: indexOf
的运行时复杂度为O(n)
,因此不建议在同一数组的循环中使用 function,因为这会给你O(n^2)
运行时,这是非常糟糕的.
O(n)
缩减函数,如findIndex
、 find
、 includes
和lastIndexOf
。indexOf
(和其他)仅在Array.prototype
上定义,因此它不适用于其他类型的可迭代对象,例如NodeList
。 在 ejs 中, 您可以使用Array.prototype.map
的重载,它为您提供每个element
的index
,并将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>
<% }%>
这可以进一步简化:
Object.assign
的替代方案,可以使用object 传播运算符...obj
:
{ index: idx, ...e }
在语义上几乎等同于Object.assign( { index: idx }, e )
。
Object.assign
将调用自定义setter
函数,而...
语法不会。map
中返回对象文字时,您需要将对象文字的大括号{}
括在圆括号()
中,以防止大括号被解析为 function 正文定界符,因此=> ({ foo: bar })
而不是=> { foo: bar }
。index: idx
可以通过将idx
参数重命名为index
并只放置{ index, ...e }
来简化。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.