0

I'm just learning how to use javascript classes. I'm having some difficulty understanding how to make event listeners call methods within a class. Specifically, whenever I call the this.infoBoxActive on click, all my variables in the method return undefined.

What I eventually want to do is have a toggle method that onclick switches between true and false and then calls either infoBoxActive or infoBoxDective based on its state. I've been playing around with my code most of the day trying various things but I seem to be sparking the same issue of my variables going undefined. If I call the method direct my everything works great.

I've been using a promise to gather my data from a local JSON file, but I wasn't sure how to return the Object in my resolve so right now I'm calling all my new classes from the promise. I don't know if this would be part of the problem.

I've tried reading some posts of similarity, but either I wasn't able to understand the solution or it wasn't pertaining to my exact problem, so I apologize if this is a duplicate.

class EpisodeInfoBox extends Episode {
  constructor({ title, date, description, tracklist } = {}) {
    super({ title, date, description, tracklist })

    this.titleContainer = document.querySelector('.episode-title');
    this.dateContainer = document.querySelector('.episode-date');
    this.descriptionContainer = document.querySelector('.episode-description');
    this.tracklistContainer = document.querySelector('.episode-tracklist');

    this.infoBoxButton = document.getElementById('infoBoxButton');

    this.infoBoxButton.addEventListener('click', this.infoBoxActive);
  }



  infoBoxActive(){
    this.titleContainer.innerHTML = this.title;
    this.dateContainer.innerHTMLs = this.date;
    this.descriptionContainer.innerHTML = this.description;

    // Creates list-items for track list
    let tracklistHTML = '';
    for (let i = 0; i < this.tracklist.length; i++) {
      tracklistHTML += `<li>${this.tracklist[i].song} - ${this.tracklist[i].artist}</li>`;
    }
    this.tracklistContainer.innerHTML = tracklistHTML;
  }
}

my promise

export default function service(url) {
  return new Promise(function(res, rej) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.onreadystatechange = handleResponse;
    xhr.onerror = function(error) {
      rej(error)
    }
    xhr.send();

    function handleResponse() {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
          var resObject = JSON.parse(xhr.responseText);
          res(resObject)
        } else {
          rej(this.statusText)
        }
      }
    };
  });
}

My resolve

function callService(){
  service('/data/episodes.json')
    .then(retrieveEpisode)
    .then(makeEpisode)
    .catch(function(e) {
      console.log(e)
    });
}

function retrieveEpisode(episodeArray) {
  return episodeArray[0];

}

function makeEpisode(episode){
  let newEpisode = new Episode(episode);
    newEpisode.setEpisodeImage();
  let newAudioPlayer = new AudioPlayer(episode);
  let newEpisodeInfoBox = new EpisodeInfoBox(episode);
}
4

1 回答 1

1

改变这个:

 this.infoBoxButton.addEventListener('click', this.infoBoxActive);

对此:

this.infoBoxButton.addEventListener('click', this.infoBoxActive.bind(this));

当调用事件侦听器时,它不会this设置对象的指针,因此infoBoxActive()使用不适当的值调用,this因此您看不到您期望的属性。您可以使用.bind()如上所示this在调用您的方法之前重新附加适当的值。


在 Javascript 中,当您this.infoBoxActive作为参数传递给函数时,.infoBoxActive会传递对该方法的引用,但与this. 它只是对函数的引用。因此,侦听器然后调用该函数并设置它自己的值,this该值将不是您的对象。使用.bind()您可以创建一个函数存根,该函数存根将this在调用您的函数时为您设置值。

于 2016-11-11T23:27:33.710 回答