遍历json数组列表

时间:2019-02-13 17:26:23

标签: javascript html json

我们两周前才刚开始3个学期,正在学习基本的事件/ Dom /获取操作。

我应该从https://jsonplaceholder.typicode.com/users获取数据并获取所有姓名和电话号码。

这就是我所做的:

Intent
setResult()

如您所见,我设法吸引了单个用户,这不是问题,但是尝试获取多个数据行对我来说似乎很麻烦。我尝试了3种不同的方法,所有这些方法始终只给我阵列中的最后一个人,尽管如果我将其打印到控制台,它也会给我全部。

请帮助我。

5 个答案:

答案 0 :(得分:2)

您需要在循环外初始化结果字符串,并在循环结束后设置HTML的值。

/* 
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

var userID = document.getElementById("userID");
const url1 = "https://jsonplaceholder.typicode.com/users/";
const url2 = "https://jsonplaceholder.typicode.com/users";
//JSON.stringify(data)
function getUser() {
  fetch(url1 + userID.value)
    .then(res => res.json())
    .then(data => {
      var all = "<p>" + "Name: " + data.name + "</p>";
      all += "<p>" + "Phone: " + data.phone + "</p>";

      document.getElementById("singleUser").innerHTML = all;
    });
}

//***************Code that needs look on is right here ********************

function getAllUsers() {
  fetch(url2)
    .then(res => res.json())
    .then(data => {
      // Traditional for loop
      var all = "";
      for (var i = 0; i < data.length; i++) {
        //console.log(data[i]);
        all += "<p>" + "Name: " + data[i].name + "</p>";
        all += "<p>" + "Phone: " + data[i].phone + "</p>";
      }
      document.getElementById("allUsers").innerHTML = all;

      // Enhanced for loop
      var users = "";
      data.forEach(function(key) {
        users += "<p>" + "Name: " + key.name + "</p>";
        users += "<p>" + "Phone: " + key.phone + "</p>";
      });
      document.getElementById("allUsers").innerHTML = users;

      // Mapped to string
      document.getElementById("allUsers").innerHTML = users.map(user => {
        return "<p>" + "Name: " + user.name + "</p>" +
               "<p>" + "Phone: " + user.phone + "</p>";
      }).join(""); 
    });
}
<h1>Hello World!</h1>
<h1>Test if deployed on Tomcat via Travis Ci</h1>
<h6>Calculator Client</h6>

<input type="number" id="firstNumber"><br>
<input type="number" id="secondNumber"><br>
<div id="operations">
  <button name="opr">+</button>
  <button name="opr">-</button>
  <button name="opr">X</button>
  <button name="opr">/</button>
  <br>
</div>
<button id="clear">Clear</button>
<p id="result"></p>

<h6>Dynamic UI manipulation with data obtained via fetch</h6>

<input type="number" id="userID">
<button onClick="getUser()">Get user</button>
<button onClick="getAllUsers()">Get all</button>
<br>
<div id="singleUser"></div>
<div id="allUsers"></div>

<script src="calculator.js" type="text/javascript"></script>
<script src="fetch.js" type="text/javascript"></script>

答案 1 :(得分:2)

您的所有问题都在这里(通常):document.getElementById("allUsers").innerHTML = all;

document.getElementById("allUsers").innerHTML行允许您直接访问DOM元素的字符串内容。 在您的情况下,您需要在此DOM上追加多行,因此只需将影响替换为附加影响。只需将=更改为+=

这是您需要做的修改:

for (var i = 0; i < data.length; i++) {                   
    console.log(data[i]);
    var all = "<p>" + "Name: " + data[i].name + "</p>";
    all += "<p>" + "Phone: " + data[i].phone + "</p>";
    document.getElementById("allUsers").innerHTML += all;
} 

您还可以执行更高级的解决方案:

let html = "";

for (let i = 0; i < data.length; i++) {                   
    console.log(data[i]);

    html += "<p>" + "Name: " + data[i].name + "</p>";
    html += "<p>" + "Phone: " + data[i].phone + "</p>";
}

document.getElementById("allUsers").innerHTML = html;

我还没有测试代码,但是应该可以!

就您所知,您还应该学习在哪里使用varlet

  • var用于全局变量,因为可以使用window.hello从任何地方访问它们(如果您的变量具有“ hello”的名称)。
  • let应该用于局部变量,因为只能在相同范围内访问它们。

答案 2 :(得分:1)

这是一个简单的逻辑错误,与您输出数据的方式有关。您已输入:

document.getElementById("allUsers").innerHTML = users;

在您的循环内。这意味着每次循环运行时,都会将“ allUsers”的值设置为users字符串,该字符串将替换以前在该空间中的任何内容。此外,每次循环运行时,也会重置users字符串,并且仅包括从当前循环迭代中获取的用户。通过执行这两项操作,您将丢弃所有先前的数据。这种操作发生得足够快,您实际上在屏幕上看到的只是最后一个(即使从技术上讲,所有其他显示都被覆盖了纳秒,然后才被覆盖!)。

您只需要确保users在循环的整个生命周期中都存在(并且将其追加而不是覆盖它),并且不要尝试将数据放入您的<div>,直到收集完所有内容。

这是固定版本:

/* 
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

var userID = document.getElementById("userID");
const url1 = "https://jsonplaceholder.typicode.com/users/";
const url2 = "https://jsonplaceholder.typicode.com/users";
//JSON.stringify(data)
function getUser() {
  fetch(url1 + userID.value)
    .then(res => res.json())
    .then(data => {
      var all = "<p>" + "Name: " + data.name + "</p>";
      all += "<p>" + "Phone: " + data.phone + "</p>";

      document.getElementById("singleUser").innerHTML = all;
    });
}

//***************Code that needs look on is right here ********************

function getAllUsers() {
  fetch(url2)
    .then(res => res.json())
    .then(data => {
      var users = ""; //declare empty string
      data.forEach(function(key) {
        //append to the string
        users += "<p>" + "Name: " + key.name + "</p>";
        users += "<p>" + "Phone: " + key.phone + "</p>";
        console.log(key.name);
      });
      //wait until the string contains everyone before we add it to the page!
      document.getElementById("allUsers").innerHTML = users;
    });
}
<h1>Hello World!</h1>
<h1>Test if deployed on Tomcat via Travis Ci</h1>
<h6>Calculator Client</h6>

<input type="number" id="firstNumber"><br>
<input type="number" id="secondNumber"><br>
<div id="operations">
  <button name="opr">+</button>
  <button name="opr">-</button>
  <button name="opr">X</button>
  <button name="opr">/</button>
  <br>
</div>
<button id="clear">Clear</button>
<p id="result"></p>

<h6>Dynamic UI manipulation with data obtained via fetch</h6>

<input type="number" id="userID">
<button onClick="getUser()">Get user</button>
<button onClick="getAllUsers()">Get all</button>
<br>
<div id="singleUser"></div>
<div id="allUsers"></div>

<script src="calculator.js" type="text/javascript"></script>
<script src="fetch.js" type="text/javascript"></script>

答案 3 :(得分:1)

在循环中,设置innerHTML每次都会替换内容。如果要追加,请考虑创建新节点。

// Create new paragraph
var name = document.createElement("p");
// Set text content to name value
name.appendChild(document.createTextNode(data[i].name));
// Append paragraph to #allUsers element
document.getElementById("allUsers").appendChild(name);
// Create new paragraph
var phone = document.createElement("p");
// Set text content to phone value
phone.appendChild(document.createTextNode(data[i].phone));
// Append paragraph to #allUsers element
document.getElementById("allUsers").appendChild(phone);

答案 4 :(得分:1)

您的循环中有问题。 请参阅下面的代码,该代码将附加到DOM的内容排除在循环之外。

  var users = ""; // So that you will not initialize it every time you iterate the loop
  data.forEach(function(key) {
    users += "<p>" + "Name: " + key.name + "</p>";
    users += "<p>" + "Phone: " + key.phone + "</p>";        
    console.log(key.name);
  });
  document.getElementById("allUsers").innerHTML = users; // So that you will change the DOM/ UI only once with all the date.

分析:

由于您要在每次迭代中初始化和更改users变量,因此它将仅具有该迭代的值。这就是为什么您最终拥有姓氏的原因。 (如果您每次都附加到一个不同的DOM位置,但是太复杂了,这将得到纠正。)