1

我正在尝试使用jQuery (AJAX) 从 GitHub API 获取一些数据,并将其附加到静态网页中。下面是我的 HTML 和 JS 片段。

        $(document).ready(function(){
            $.ajax({
                url: 'https://api.github.com/repos/FearlessPython/Basics-of-Python',
            }).done(function(repo){
                $('#heading').html(`${repo.name}<hr>`);
                $('#stats').html(`
                    <strong>Stars</strong>: ${repo.stargazers_count} <br>
                    <strong>Watchers</strong>: ${repo.watchers_count} <br>
                    <strong>Language</strong>: ${repo.language} <br>
                    <strong>Open Issues</strong>: ${repo.open_issues_count} <br>
                    <strong>License</strong>: ${repo.license.name}<br>
                `);
            });
            $.ajax({
                method: "GET",
                url: "https://api.github.com/repos/FearlessPython/Basics-of-Python/contributors",
                dataType: "json"
            }).done(function(data){
                $.each(data, function(index, url){
                    $.ajax({
                        url: data[index].url
                    }).done(function(individual_contributor){
                        // console.log(data[index].url);
                        $('ul#users').append(`
                            <li><strong>${individual_contributor.name}</strong></li>
                            <li><strong>Bio:</strong> ${individual_contributor.bio}</li>
                            <li><strong>Public Repos:</strong> ${individual_contributor.public_repos}</li>
                            <li><strong>Followers:</strong> ${individual_contributor.followers}</li>
                            <li><strong>Following:</strong> ${individual_contributor.following}</li>
                        `)
                    });
                });
                $.map(data, function(contributor, i){
                    // contrb.push(contributor);
                    $('ol#contributors').append(`
                    <li><a href="${contributor.html_url}" target="_blank">${contributor.login}</a></li>

                    <img src = "${contributor.avatar_url}" style = "float: right;" width=10%>   
                    <ul id="users"></ul>
                    `);
                });
            });
        });
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
</head>
<body>Here, dynamic statistics are available regarding this repository in GitHub.

    <div id="statistics">
        <h3 id="heading"></h3>
        <ul id="stats"></ul>
        <h4>Contributors</h4><hr>
        <ol id="contributors">
            <!-- <ul id="users"></ul> -->
        </ol>
    </div>
</body>
</html>

你可以看到,在每个用户下,同样的事情一次又一次地迭代。使用.html()而不是.append()覆盖第一次迭代数据,并且所有内容都被最新迭代的数据替换。理想的结果应该是这样的:

所需视图

我也尝试使用for循环,但同样的事情正在发生。我试图从最近几天开始解决它,但无法解决它。我刚刚开始使用 jQuery 和 AJAX。

注意:如果 GitHub API 请求超出您的要求,您将无法看到上述代码片段的结果。所以我还包括网页当前情况的图像。

在此处输入图像描述

4

1 回答 1

1

获得贡献者列表后,您将执行两次迭代。,$.each您在其中发出请求以获取贡献者详细信息,该详细信息将附加到带有id='users'. (这还不存在!)

$.each(data, function(index, url){
   // request contributor details
}

并且$.map将登录名和头像附加到列表中,也附加到容器中 <ul id='users'>

$.map(data, function(contributor, i){
    $('ol#contributors').append(`
     <li><a href="${contributor.html_url}" target="_blank">${contributor.login}</a></li>
     <img src = "${contributor.avatar_url}" style = "float: right;" width=10%>   
     <ul id="users"></ul>`  // this will cause you trouble
);
});

现在,id 在 document 中应该是唯一的,因此附加具有相同 id 的额外元素不会按预期工作。

看,你有一个竞速条件,你的贡献者详细信息处理程序依赖于你尚未创建的元素。无论如何,当它解析时,它的内容将附加到查找时找到的任何元素$('#users'),很可能是 DOM 中的第一个元素。

围捕:

  • 只对贡献者列表执行一次迭代
  • 将贡献者详细信息附加到相应的用户<ul>
  • 不要为要在列表中重复的容器使用 id(或至少计算其 id 而不是硬编码)

当您获得列表时,我会使用for..of. 然后在每个循环中,我将声明<ul>元素(变为块范围)并在子请求解决时使用该引用来附加用户详细信息。

  for (let contributor of contributors) {
    // block scoped
    let userDetailsElement = $('<ul class="users"></ul>');

    $('ol#contributors')
      .append(userHeader(contributor))
      .append(userDetailsElement);

    $.getJSON(contributor.url)
     .then( individual_contributor => {
      // I know   which <ul> I'm appending to
        userDetailsElement.append(
              contributorDetailsHtml(individual_contributor)
        );
    });
  }

在下面的代码片段中,我将 jQuery 的回调声明为异步的,因此我也可以等待贡献者的详细信息,就像

let individual_contributor = await $.getJSON(contributor.url);

userDetailsElement.append(
              contributorDetailsHtml(individual_contributor)
        );

等待每个用户的详细信息意味着请求将按顺序运行,而触发 thenable 请求将并行执行。如果你要查询一个包含数百个贡献者的 repo,那么这个选择不仅会因为性能,而且因为你会受到限制并且你的 dom 的一部分不会渲染。

const repoUrl = 'https://api.github.com/repos/FearlessPython/Basics-of-Python';

function repoStatsHtml(repo) {
  return `
    <strong>Stars</strong>: ${repo.stargazers_count} <br>
    <strong>Watchers</strong>: ${repo.watchers_count} <br>
    <strong>Language</strong>: ${repo.language} <br>
    <strong>Open Issues</strong>: ${repo.open_issues_count} <br>
    <strong>License</strong>: ${repo.license.name}<br>
    `;
}

function contributorDetailsHtml(individual_contributor) {
  return `
    <li><strong>${individual_contributor.name}</strong></li>
    <li><strong>Bio:</strong> ${individual_contributor.bio}</li>
    <li><strong>Public Repos:</strong> ${individual_contributor.public_repos}</li>
    <li><strong>Followers:</strong> ${individual_contributor.followers}</li>
    <li><strong>Following:</strong> ${individual_contributor.following}</li>
                        `;
}

function userHeaderHtml(contributor) {
  return `
    <li><a href="${contributor.html_url}" class="login" target="_blank">${contributor.login}</a></li>
    <img src = "${contributor.avatar_url}" class="avatar">   
                    `;
}
$(document).ready(async function() {
  $.getJSON(repoUrl).done(function(repo) {
    $('#heading').html(`${repo.name}<hr>`);
    $('#stats').html(repoStatsHtml(repo));
  });
  let contributors = await $.getJSON(`${repoUrl}/contributors`);

  for (let contributor of contributors) {
    let userDetailsElement = $('<ul class="users"></ul>');
    $('ol#contributors')
      .append(userHeaderHtml(contributor))
      .append(userDetailsElement);
    $.getJSON(contributor.url).then(individual_contributor => {
      userDetailsElement.append(
        contributorDetailsHtml(individual_contributor)
      );
    });
  }

});
.users {
  min-width: 90px;
  min-height: 90px;
  margin-bottom: 0.5em;
}

.avatar {
  float: right;
  width: 10%;
}

.login {
  margin-top: 0.5em;
  font-size: 1.1em;
  text-decoration: none;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://code.jquery.com/jquery-3.5.1.js" integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc=" crossorigin="anonymous"></script>
</head>

<body>Here, dynamic statistics are available regarding this repository in GitHub.

  <div id="statistics">
    <h3 id="heading"></h3>
    <ul id="stats"></ul>
    <h4>Contributors</h4>
    <hr>
    <ol id="contributors">
    </ol>
  </div>
</body>

</html>

于 2020-08-29T07:58:08.613 回答