为什么在加载数据后在控制台中使用此方法,但与元素上的事件一起使用时却不能使用呢?

时间:2018-12-24 06:06:53

标签: javascript ajax addeventlistener

我一直试图弄清楚为什么addEventListener不能与此功能一起使用。加载数据后,players.getRushingYards()在控制台中工作。几周前,我问了一个类似的问题,并指出了引用“ this”关键字的问题。我什至没有使用它,所以不确定如何应用。我不执行需要的回调或其他操作吗?我尝试将数据复制到名为“ players”的对象,返回数据后,它可以在控制台中运行,但是再次使用侦听器告诉我,players.data是未定义的。如果有人可以提供帮助,将不胜感激。我尝试使用简单的函数,但我对绑定,应用,调用等的了解无济于事。

window.addEventListener('load', getStats);
let players = {};
const xhr = new XMLHttpRequest
let output = "";
let txt;

// EXPORT AJAX REQUEST FOR STATS VIA MODULE
function getStats(e) {
  // const number = document.querySelector('input[type="number"]').value;();
  xhr.open('GET', `https://api.fantasydata.net/v3/nfl/stats/JSON/PlayerSeasonStats/2018`, true);
  xhr.setRequestHeader("Ocp-Apim-Subscription-Key", "api key goes here");

  xhr.onload = function () {
    if ( xhr.readyState === 4 && xhr.status === 200 ) {
      players.data = JSON.parse(xhr.response);
      console.log(players.data)
    }
    return players;
  }
  xhr.send();
  e.preventDefault();
  return players;
}

players.getRushingYards = () => {
  output = "";
  sorted = players.data.filter((el, ind) => {
    if ( el.RushingYards > 0 ) {
      return el
    }
  }).sort((a, b) => {
    if ( a.RushingYards  < b.RushingYards ) {
      return 1;
    }
    if ( a.RushingYards  > b.RushingYards ) {
      return -1;
    }
  });

  sorted.forEach((el, ind) => {
    output+= `<tr><td>${el.Name}</td><td>${el.RushingYards}</td><td>${el.RushingTouchdowns}</td><td>${el.ReceivingYards}</td><td>${el.ReceivingTouchdowns}</td><tr>`;
  })  

  let headers = `<th>Name</th><th>Rush Yards</th><th>Rush TD</th><th>Receiving Yards</th><th>Receiving TD</th>`;

  let combined = headers + output;

  document.querySelector(".stats").innerHTML = combined;
}

document.querySelector(".rushing-yards").addEventListener("click", players.getRushingYards);

返回的数据是数组中的对象,看起来像这样(数组中的典型JSON解析对象-为简洁起见,我删除了大多数属性)

response = [{
Name: "B.McManus"
ReceivingLong: 0
ReceivingTargets: 0
ReceivingTouchdowns: 0
ReceivingYards: 0
ReceivingYardsPerReception: 0
ReceivingYardsPerTarget: 0
ReceptionPercentage: 0
Receptions: 0
RushingAttempts: 0
RushingLong: 0
RushingTouchdowns: 0
RushingYards: 0
RushingYardsPerAttempt: 0},
{
Name: "E.Elliott"
ReceivingLong: 0
ReceivingTargets: 0
ReceivingTouchdowns: 0
ReceivingYards: 0
ReceivingYardsPerReception: 0
ReceivingYardsPerTarget: 0
ReceptionPercentage: 0
Receptions: 23
RushingAttempts: 192
RushingLong: 0
RushingTouchdowns: 11
RushingYards: 1250}]

2 个答案:

答案 0 :(得分:0)

您正在使用getStats方法发出异步(AJAX)请求,一旦从服务器收到响应,就会执行onload方法。因此,从服务器接收的数据不可用于您的players.getRushingYards,因为它是在从服务器接收响应之前执行的。 您可以做的是将回调方法传递给getStats并在收到AJAX的数据后调用它,例如

function getStats(e, done) {
// done is the callback
// open XHR and set headers
xhr.onload = function () {
    if ( xhr.readyState === 4 && xhr.status === 200 ) {
        players.data = JSON.parse(xhr.response);
        console.log(players.data)
    }
    return done(players);
}
// xhr.send();

或者您可以按照getStats方法复制代码并将其粘贴到onload中。

xhr.onload = function () {
    if ( xhr.readyState === 4 && xhr.status === 200 ) {
        players.data = JSON.parse(xhr.response);
        console.log(players.data)
        // code to process players object 
    }
  }

您可以签出this进行进一步的澄清/阅读。

答案 1 :(得分:0)

在执行getStats()之前,在事件侦听器中未定义

players.data。 您是否可以尝试在第二行中声明让玩家= {数据:[]},以查看是否仍然存在此问题。