Как передать пользовательскую функцию внутри функции .map для вновь созданного элемента? - PullRequest
0 голосов
/ 18 марта 2020

Я заполняю <ul></ul> с помощью <li></li>, используя fetch метод API-запроса.

UL выглядит следующим образом:

<ul id="todos" class="collection">
</ul>

Сценарий, который заполняет todos:

fetch("http://localhost:3000/api/todos")
.then((resp) => resp.json())
.then((data) => {
  let todos = data;
  return todos.map(todo => {
    let liTodo = createNode("li");
    liTodo.innerHTML = '<button class="btn-small remove-todo" onclick="' + deleteTodo(`${todo._id}`) + '">Delete' + '</button>';
    liTodo.classList.add("collection-item");
    append(ulTodos, liTodo);
});

function createNode(element) {
  return document.createElement(element); // Create the type of element you pass in the parameters
}

function append(parent, el) {
  return parent.appendChild(el); // Append the second parameter(element) to the first one
}

function deleteTodo(id) {
  console.log("deleteTodo function called " + id);
}

enter image description here

Проблема: После загрузки страницы и проверки console я вижу, что deleteTodo() функция вызывается, хотя я не щелкнул по ней.

Знаете ли вы, как я могу правильно передать deleteTodo() с id только при нажатии?

Любая помощь очень ценится. Спасибо.

Ответы [ 4 ]

1 голос
/ 18 марта 2020

Вы можете избежать использования другой функции-оболочки, используя ES6 backticks для всего элемента кнопки.

Таким образом, функция не будет вызываться до события, так как она считается строкой.

Смотрите здесь рабочий пример:

const ulTodos = document.getElementById('todos');

function myFetch() {
  let todos = [{id:1, text: "a"}, {id:2, text: "b"}, {id:3, text:"c"}];
  
  return todos.map(todo => {
    let liTodo = createNode("li");
    liTodo.innerHTML = `<button class="btn-small remove-todo" onclick="deleteTodo('${todo.id}')">Delete</button>`;
    liTodo.classList.add("collection-item");
    append(ulTodos, liTodo);
  });
}


function createNode(element) {
  return document.createElement(element); // Create the type of element you pass in the parameters
}

function append(parent, el) {
  return parent.appendChild(el); // Append the second parameter(element) to the first one
}

function deleteTodo(id) {
  console.log("deleteTodo function called " + id);
}
  
  
myFetch();
<ul id="todos" class="collection"></ul>
1 голос
/ 18 марта 2020

Вы можете преобразовать в функцию стрелки.

Вместо

function deleteTodo(id) {
  console.log("deleteTodo function called " + id);
}

Использовать

const deleteTodo = (id) => {
  console.log("deleteTodo function called " + id);
}
1 голос
/ 18 марта 2020

Когда вы соединяете внутреннюю HTML следующим образом:

'...click="' + deleteTodo(`${todo._id}`) + '"...'>

Функция deleteTodo вызывается немедленно, что возвращает undefined.

И фактически внутреннюю HTML у вас есть:

<button class="btn-small remove-todo" onclick="undefined">Delete</button>'

Итак, не называйте это, просто примите это как строку.

liTodo.innerHTML = `<button class="btn-small remove-todo" onclick="deleteTodo(${todo._id})">Delete</button>`;
1 голос
/ 18 марта 2020

Вы вызываете deleteTodo по незнанию. Оберните вызов по клику в функции стрелки.

liTodo.innerHTML = '<button class="btn-small remove-todo" onclick="() => deleteTodo(' + `${todo._id}` + ')">Delete' + '</button>';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...