使用mustache.js将数组数据呈现为表行;坚持执行行编辑

时间:2018-07-14 19:49:33

标签: javascript html-table mustache

我正在创建一个用于跟踪费用的应用。

Here is a codepen with all of the source code.

Expense Tracking App Screenshot


我有一个名为object的全局对象,将其渲染为Mustache模板:

var object = {
    info : [
        {date: "14, July", day: "Saturday", item: "Lunch", price: 40}
        {date: "15, July", day: "Sunday", item: "Airport", price: 80}
        {date: "14, July", day: "Saturday", item: "Snacks", price: 25}
    ],
    withdrew: 0
};
{{#info}}
<tr>
    <td>{{date}}</td>
    <td>{{day}}</td>
    <td>{{item}}</td>
    <td>{{price}} /-</td>
    <td><a href="#" id="editInfo">Edit</a> | <a href="#" id="deleteInfo">Delete</a></td>
</tr>
{{/info}}
Mustache.render(template, object);

当用户在 Add Item div(在屏幕截图的右侧)中输入详细信息时,info中的object数组将被填充(当前有3个条目)。


当用户单击“修改”表列中的“编辑”或“删除”按钮时,我停留的部分是编辑一行。我将以下单击侦听器绑定到该表:

var modifyBtn = document.querySelector('table');
modifyBtn.addEventListener('click', function(e){
    console.log(e.target);
});

这样,我可以使用console.log()正确地获得两个按钮节点,但是如何使它们唯一地指向生成每一行的原始数组元素呢?

我们非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

有两种方法可以做到这一点,但是立即让我脱颖而出的方法如下:

  1. 将索引添加到Mustache渲染功能的数组元素中
  2. 将索引呈现为HTML中的data-属性
  3. 在点击监听器中检索此数据
  4. 使用此数据修改原始的info数组

让我们来解决这个问题。


步骤1:将索引添加到Mustache渲染功能的数组元素中

首先,我们要检索HTML中的数组索引。在使用Mustache渲染时,默认情况下该数据不可用,因此我们需要将其添加到我们自己中。 不能永久添加到数组对象。实际索引可以随时更改(例如,如果元素被删除)。相反,我们只想呈现HTML的索引,而没有其他地方

创建以下addIndexes()函数:

function addIndexes(object) {
    object = JSON.parse(JSON.stringify(object));
    var info = object.info;

    for (var i = 0; i < info.length; i++) {
        info[i].index = i;
    }

    return object;
}
  • 第一行克隆对象。记住,我们不想修改原始对象或数组。这样一来,我们便可以处理不会影响原件的副本。
  • 我们遍历数组并将该数组的索引添加到名为index的属性中。

var object = {
    info : [
        {date: "14, July", day: "Saturday", item: "Lunch", price: 40},
        {date: "15, July", day: "Sunday", item: "Airport", price: 80},
        {date: "14, July", day: "Saturday", item: "Snacks", price: 25}
    ],
    withdrew: 0
};

function addIndexes(object) {
    object = JSON.parse(JSON.stringify(object));
    var info = object.info;

    for (var i = 0; i < info.length; i++) {
        info[i].index = i;
    }

    return object;
}

console.log("--- The object AFTER addIndexes() ---");
console.log(addIndexes(object));

console.log("--- The object BEFORE addIndexes() ---");
console.log(object);

现在,只需修改Mustache.render()方法以使用我们新的addIndexes()函数:

function refreshDOM() {
    var outputBody = Mustache.render(template, addIndexes(object));
    ...
}

步骤2:将索引呈现为HTML中的data-属性

现在,我们需要在HTML模板中附加这些索引。在您的主index.html中,转到渲染功能并更改按钮代码以使其内容如下:

<td><a href="#" id="editInfo" data-index="{{index}}">Edit</a> | <a href="#" id="deleteInfo" data-index="{{index}}">Delete</a></td>

现在,我们将索引输出到data-index属性,稍后可以检索该属性。这样可以渲染每个按钮元素,使其看起来像这样:

<td><a href="#" id="editInfo" data-index="0">Edit</a> | <a href="#" id="deleteInfo" data-index="0">Delete</a></td>
<td><a href="#" id="editInfo" data-index="1">Edit</a> | <a href="#" id="deleteInfo" data-index="1">Delete</a></td>

依此类推,对于每一行。

第3步:在点击监听器中检索此数据

我们现在可以实际处理这些数据了。将您的modifyBtn点击事件监听器更改为以下内容:

var modifyBtn = document.querySelector('table');
modifyBtn.addEventListener('click', function(e){
    var el = e.target;
    var action = el.id;
    var index = parseInt(el.dataset.index);

    switch (action) {
        case "editInfo": editInfo(index); break;
        case "deleteInfo": deleteInfo(index); break;
    }
});
  • 我们现在从el获取event.target(仅仅是元素)。
  • 我们可以从您的el.id获取带有操作(例如“ editInfo”)的字符串。
  • 索引值为data-index,可以用el.dataset.index检索。请注意,这是作为字符串放置在HTML中的(我们不能使用),因此我们必须对其运行parseInt()才能从字符串中获取整数。
  • 使用switch语句,我们现在可以根据ID执行操作。

这些处理程序函数(editInfo()deleteInfo())目前都未声明,因此进入最后一步!

步骤4:使用此数据修改原始的info数组

我不知道您想使用editInfo ID做什么,所以我将这个留给您。我在点击监听器的上方直接创建了一个简单的deleteInfo函数:

function deleteInfo(index) {
    object.info.splice(index, 1);
    refreshDOM();
}

这将从全局object.info数组中删除指定的索引,然后调用refreshDOM()进行更新。


我们现在完成了!抱歉,这是一个冗长的回答,我想细分我们进行的每一步。让我知道这一切是否有意义以及您是否有任何疑问!