【问题标题】:Returning Index of Row & Col in the Template Table返回模板表中行和列的索引
【发布时间】:2017-09-23 13:30:50
【问题描述】:

我有一个动态表,我通过Handlebars.js 创建作为模板,问题是我不能将 id 分配给每个单元格,将它们的位置表示为行和列。我有下面的模板,

<script id="td-template" type="text/x-handlebars-template">
    {{#each ships}}
    <tr>
        <td class='left-aligned'>{{this.name}}</td>
        <td class="default" id="id{{@index}}"></td>
        <td class="default" id="id{{@index}}"></td>
        <td class="default" id="id{{@index}}"></td>
        <td class="default" id="id{{@index}}"></td>
        <td class="default" id="id{{@index}}"></td>
        <td class="default" id="id{{@index}}"></td>
        <td class="default" id="id{{@index}}"></td>
        <td class="default" id="id{{@index}}"></td>
    </tr>
    {{/each}}
</script>

第一个返回 0,第二个循环返回 1,反之亦然。我需要的是添加一个公式而不是 {{@index}} 但它不会让我像破坏 html 或表格本身那样添加。

我会打开任何类似 JQuery 的建议,而不是 Handlebars.js

【问题讨论】:

  • 为什么需要这个?通常只需在其事件处理程序中找出元素的索引即可减少工作量(并且更易于维护)。这甚至不需要在元素上添加id
  • 我有一个表格,例如 5 行到 3 列的表格,并尝试任意给每个单元格一个唯一的 ID,如 1、2、3、4 等。我想不出任何解决方案,但如果你知道的话,你可以建议任何更简单的方法..
  • @index 是船舶数组中的船舶 ID/索引?
  • 是的@Oskar,我尝试使用 for 循环,但也无法在模板中实现它。

标签: javascript jquery handlebars.js template-engine indexof


【解决方案1】:

您可以使用块参数:http://handlebarsjs.com/block_helpers.html#block-params

连同数据属性:https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes

还要执行算术运算,您必须定义一个助手:http://handlebarsjs.com/#helpers

另外,我会将id 移动到tr 节点下:

Handlebars.registerHelper("eval", function() {
  let args = Array.from(arguments);
  args.pop(); //remove the unwanted object from args list
  return eval(args.join(''));
});

var context = {
  ships: [{
    name: 'battleship',
    id: 1,
    column0: 'says',
    column1: 'hello',
    column2: 'world'
  }, {
    name: 'titanic',
    id: 2,
    column0: 'yields',
    column1: 'hi',
    column2: 'world'
  }]
};

$('#dropzone').append(Handlebars.compile($("#td-template").html())(context));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.6/handlebars.js"></script>

<script id="td-template" type="text/x-handlebars-template">
  {{#each ships as |ship i|}}
  <tr data-id="{{ship.id}}">
    <td class="left-aligned" data-id="{{eval i '*4' }}">{{ship.name}}</td>
    <td class="default" data-id="{{eval i '*4+1' }}">{{ship.column0}}</td>
    <td class="default" data-id="{{eval i '*4+2' }}">{{ship.column1}}</td>
    <td class="default" data-id="{{eval i '*4+3' }}">{{ship.column2}}</td> 
  </tr>
  {{/each}}
  
</script>

<table id="dropzone"></table>

那么为了从tr节点获取id:

$(tr).data('id');

【讨论】:

  • 非常感谢,但是,我主要是继续计数。我的意思是,如果第一行是“测试 1,测试 2,测试 3”,那么第二行将是“测试 4,测试 5,测试 6”,依此类推。但这完全不同,我对船只本身有“身份”。你有其他解决方案吗?
  • @ErhanYaşar 我更新了我的答案,起初没有发现你需要每行和每列累积值
  • 嗯,除了船舶上下文中的“shipName”之外,我还有单独的“shipID”。所以我的主要目标只是通过分配不同的 id 来了解表格单元格,稍后我将调用这些 id 来操作它们。我每次都使用每列的模板添加这些行。无论如何,您的解决方案也解决了这个问题,但它需要每次静态分配 columnCount 内的列值。我什至试图找到一种动态的方式来编写 columnCount: Array(5).fill(5) 但没有找到。你有什么想法吗??
  • @ErhanYaşar 用shipID 很好,只需用ship.shipId 替换shipId 我仍然不明白你想如何生成你的列,它们是来自每个ship 的字段还是你想要的手动添加?
  • 我编辑了这个问题,以便向您展示案例的较小版本。您的解决方案使用静态答案而不是动态方式解决。如果你能重现一种思维方式,那就欣赏并学习一种新的方式。
【解决方案2】:

你可以定义一个辅助函数,像这样:

var columnsCount = 3; // change this to the total number of columns per row in your table.
Handlebars.registerHelper("multiply", function(index, count){
    return (index * columnsCount) + count;
});

然后使用以下方式设置 ID:

<script id="td-template" type="text/x-handlebars-template">
    {{#each ships}}
    <tr>
        <td class='left-aligned'>{{this.name}}</td>
        <td class="default" id="id{{multiply @index 1}}"></td>
        <td class="default" id="id{{multiply @index 2}}"></td>
        <td class="default" id="id{{multiply @index 3}}"></td>
        .....
    </tr>
    {{/each}}
</script>

这是一个展示这种方法在行动中的片段:

var columnsCount = 3; // change this to the total number of columns per row in your table.
Handlebars.registerHelper("multiply", function(index, count){
    return (index * columnsCount) + count;
});

var context = {
  ships: [{
    name: 'ship one'
  }, {
    name: 'ship two'
  }]
};

$('#rendered').append(Handlebars.compile($("#td-template").html())(context));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.0.6/handlebars.js"></script>

<script id="td-template" type="text/x-handlebars-template">
    <table>
      <tbody>
        {{#each ships}}
        <tr>
            <td class='left-aligned'>{{this.name}}</td>
            <td class="default" id="id{{multiply @index 1}}">column {{multiply @index 1}}</td>
            <td class="default" id="id{{multiply @index 2}}">column {{multiply @index 2}}</td>
            <td class="default" id="id{{multiply @index 3}}">column {{multiply @index 3}}</td>
            <!-- and so on.... -->
        </tr>
        {{/each}}
      </tbody>
    </table>
</script>

<div id="rendered"></div>

【讨论】:

  • 感谢您的解决方案!但我无法让它正常工作。可能是因为大括号内是否缺少逗号?或者除了在我的document.ready 函数中添加你的registerHelper 函数之外,我还需要做任何额外的步骤吗?
  • @ErhanYaşar 我已经编辑了我的答案。我计算列索引的方式有误。如果您打算使用这种方法,请不要忘记更改 columnsCount 变量。
  • 其实主要是因为在我的document.ready()里面定义了Handlebars的registerHelper函数。它在我改变了它的位置并且已经与你的编辑类似的编辑之后工作了。
  • @ErhanYaşar 太好了。我很高兴能帮上忙。
  • @ErhanYaşar 我不确定,可能与您定义变量和函数的顺序有关。在调用 Handlebars.compile 之前,您必须定义 Handlebars.registerHelper("multiply", ...)
猜你喜欢
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多