Для L oop в массиве из динамического c API в формате JSON в шаблонных литералах - PullRequest
3 голосов
/ 03 августа 2020

Попытка сделать все это с как можно большим количеством Javascript ванили без необходимости React, Angular или чего-то еще. Я визуализирую содержимое HTML через свой файл JS. Как мне сделать для l oop внутри шаблонных литералов (`)? Я не могу заставить al oop работать, и он мне нужен для отображения данных в реальном времени. С кодом, который вы видите в файле JS, я вручную ввел индекс 0, чтобы получить первого астронавта из массива, и он работает и отображается нормально.

Это мой JS файл.

const apiData ={
    url: 'http://api.open-notify.org/astros.json'
}

const {url} = apiData
const apiUrl = `${url}`

fetch(apiUrl)
    .then( (data) => data.json() )
    .then ( (astronauts) => createHtml(astronauts) )

const createHtml = (data) => {
    console.log(data)
    const html = `
    <div> 
        Total People In Space: ${data.number} <br>
        Names: ${data.people[0].name} <br>
        Craft: ${data.people[0].craft}
    </div>
    `
    const astronautDiv = document.querySelector('.astronaut')
    astronautDiv.innerHTML = html
}

Вот последнее содержимое API в формате JSON.

{"number": 3, "people": [{"craft": "ISS", "name": "Chris Cassidy"}, {"craft": "ISS", "name": "Anatoly Ivanishin"}, {"craft": "ISS", "name": "Ivan Vagner"}], "message": "success"}

Вот мой HTML файл.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Space</title>
    <link rel="stylesheet" href="static/css/styles.css">
    <script src="static/js/main.js"></script>
</head>
<body>
    <div class="astronaut"></div>
</body>
</html>

Ответы [ 2 ]

4 голосов
/ 03 августа 2020

Используя .map и .join, мы можем создать строку внутри литерала шаблона

const JSONDATA = {"number": 3, "people": [{"craft": "ISS", "name": "Chris Cassidy"}, {"craft": "ISS", "name": "Anatoly Ivanishin"}, {"craft": "ISS", "name": "Ivan Vagner"}], "message": "success"}

const createHtml = (data) => {
    const html = `
    <div> 
        Total People In Space: ${data.number} <br>
        ${data.people.map(x => `<div>Name: ${x.name}, Craft: ${x.craft}</div>`).join("")}
    </div>
    `
    const astronautDiv = document.querySelector('.astronaut')
    astronautDiv.innerHTML = html
}

createHtml(JSONDATA);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Space</title>
    <link rel="stylesheet" href="static/css/styles.css">
    <script src="static/js/main.js"></script>
</head>
<body>
    <div class="astronaut"></div>
</body>
</html>
1 голос
/ 03 августа 2020

Если вы установите innerHTML элемента, он уничтожит все предыдущие innerHTML (например, других астронавтов).

Чтобы добавить несколько элементов внутри вашего div, вы можете использовать метод insertAdjacentHTML , например:

const
  astronautsDiv = document.querySelector('.astronaut'),
  myData = simulateFetchAndParse();
insertNewHtml(myData);

function insertNewHtml(data){

  // Inserts astronaut count
  const numberSpan = `<span>Total People In Space: ${data.number}</span>`;
  astronautsDiv.insertAdjacentHTML("beforeend", numberSpan);

  // Inserts individual astronaut information
  for(let person of data.people){
    const personDiv = `
      <div class="person"> 
          <div>Name: ${person.name}</div>
          <div>Craft: ${person.craft}</div>
      </div>
      `;
    astronautsDiv.insertAdjacentHTML("beforeend", personDiv);
  }
}

function simulateFetchAndParse(){
  const data = {
    number: 2,
    people: [
      { name: "Tasha Yar", craft: "Enterprise" },
      { name: "Buzz Lightyear", craft: "None" }
    ]
  };
  return data;
}
.astronaut{ margin: 1em 0 0 1em; padding: 1em 0.5em 0 0.5em; border: 1px solid grey; }
.person{ margin: 1em 0; }
<div class="astronaut"></div>

В качестве альтернативы вы можете использовать серию createElement и .appendChild вызывает (что позволяет избежать использования шаблонных литералов, в которых искаженный HTML может завершиться ошибкой во время выполнения).

Код будет выглядеть примерно так:

const
  astronautsDiv = document.querySelector('.astronaut'),
  myData = simulateFetchAndParse();
insertNewHtml(myData);


function insertNewHtml(data){

  // Makes a span with some text, and appends it to our container
  const numberSpan = document.createElement("span");
  numberSpan.textContent = `Total People In Space: ${data.number}`;
  astronautsDiv.appendChild(numberSpan);

  for(let person of data.people){

    // Makes three new divs (`personDiv` will contain the other two)
    const
      personDiv = document.createElement("div"),
      nameDiv = document.createElement("div"),
      craftDiv = document.createElement("div");

    // Sets some text and a class
    nameDiv.textContent = `Name: ${person.name}`;
    craftDiv.textContent = `Craft: ${person.craft}`;
    personDiv.classList.add("person"); // So the CSS can style this div
   
    // Adds the two divs to `personDiv`, and adds `personDiv` to our container
    personDiv.appendChild(nameDiv);
    personDiv.appendChild(craftDiv);
    astronautsDiv.appendChild(personDiv);
  }
}

function simulateFetchAndParse(){
  const data = {
    number: 2,
    people: [
      { name: "Tasha Yar", craft: "Enterprise" },
      { name: "Buzz Lightyear", craft: "None" }
    ]
  };
  return data;
}
    .astronaut{ margin: 1em 0 0 1em; padding: 1em 0.5em 0 0.5em; border: 1px solid grey; }
    .person{ margin: 1em 0; }
<div class="astronaut"></div>
...