模板文字注入对象并传递给函数

时间:2018-10-17 01:15:38

标签: javascript

我有以下代码,我想在其中使用模板文字将订单对象传递给deleteOrder函数。

function updateUI() {

    let orderItems = orders.map(function(order){
      return `<li class="order">
      <label>${order.name}</label>
      <p>${order.coffee}</p>
      <button onclick="deleteOrder(\"${order.key}\")">Remove</button>
      </li>`
    })

    ordersList.innerHTML = orderItems.join('')

}

解决方案:

function updateUI() {

    let orderItems = orders.map(function(order){
      return `<li class="order">
      <label>${order.name}</label>
      <p>${order.coffee}</p>
      <button onclick="deleteOrder('${order.key}')">Remove</button>
      </li>`
    })

    ordersList.innerHTML = orderItems.join('')

}

1 个答案:

答案 0 :(得分:2)

正如您所发现的那样,内联处理程序是不好的做法,而且很难管理。另外,以任何方式用HTML表示对象,都没有办法使它与原始对象===(例如,您不能使用includes来检查是否一个包含该对象的数组)。改用Javascript正确附加处理程序,以便可以通过其闭包引用order

let orderItems = orders.map((order) => {
  const li = document.createElement('li');
  li.className = 'order';
  li.innerHTML = `
    <label>${order.name}</label>
    <p>${order.coffee}</p>
    <button>Remove</button>`;
  li.children[2].addEventListener('click', () => {
    deleteOrder(order);
  });
  return li;
});

如果您不想使用.children[index],如果您的li只有一个button,则可以使用querySelector进行选择:

li.querySelector('button').addEventListener...

请注意,这将导致orderItems返回一个元素数组,而不是一个 strings 数组,因此不要使用结果分配给某些元素innerHTML,在容器上调用appendChild,以附加li。例如:

const lis = orderItems(orderArr);
lis.forEach((li) => {
  container.appendChild(li);
});

如果您想将order.key传递给deleteOrder而不是传递order,请替换

deleteOrder(order);

使用

deleteOrder(order.key);

尽管不应该使用内联处理程序,但要做的方法是在整个onclick属性周围使用双引号,并在order.key字符串周围使用单引号,确保转义任何order.key中的单引号或双引号:

const escapedKey = order.key.replace(/['"]/g, '\\$&');
// ...
<button onclick="deleteOrder('${escapedKey}')">Remove</button>

但是转义很丑陋而且不雅-而是使用Javascript附加处理程序。