2016-11-11 5 views
0

javascriptクラスの使い方を学んでいます。イベントリスナーがクラス内のメソッドを呼び出す方法を理解するのが難しいです。具体的には、this.infoBoxActiveをクリックすると、メソッド内のすべての変数は未定義に戻ります。クラスメソッド内のイベントリスナーを使用して、別のクラスメソッドを呼び出すundefined

私がやりたいことは、onclickがtrueとfalseを切り替えるトグルメソッドを持っていて、その状態に基づいてinfoBoxActiveまたはinfoBoxDectiveを呼び出します。私はさまざまなことを試して、ほとんどの日に自分のコードを使って遊んできましたが、私の変数の同じ問題が未定義になっているようです。メソッドを直接呼び出すと、すべてがうまく動作します。

ローカルのJSONファイルからデータを収集する約束をしていますが、私の解決策でObjectを返す方法がわからなかったので、私はすべての新しいクラスを約束から呼んでいます。これが問題の一部であるかどうかはわかりません。

類似点の記事を読んでみましたが、解決策を理解できなかったか、正確な問題には関係していなかったので、重複していると謝ります。

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; 
    } 
} 

私の約束この

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) 
     } 
     } 
    }; 
    }); 
} 

私の決意

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); 
} 

答えて

1

変更:

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

これまで:

イベントリスナーが呼び出されると0
this.infoBoxButton.addEventListener('click', this.infoBoxActive.bind(this)); 

、それはとてもinfoBoxActive()thisの不適切な値で呼び出されたので、あなたが期待するプロパティが表示されない設定、オブジェクトのthisポインタを持っていません。上記のように.bind()を使用して、メソッドを呼び出す前に適切な値を再接続することができます。 JavaScriptで


、あなたが関数の引数としてthis.infoBoxActiveを渡すとき、.infoBoxActiveメソッドへの参照が渡されますが、全くthisへの接続はありません。それは単なる関数への参照です。そのため、リスナーはその関数を呼び出し、自分のオブジェクトではないthisの値を設定します。 .bind()を使用すると、関数を呼び出すときにthisという値を設定する関数スタブを作成できます。

+0

Whoa!本当にありがとう!これを回避するためにコードをどれだけ編集しているかは分かりません。あなたの説明も素晴らしかったです。もしあなたが2番目の質問をしたら、この2番目の質問をしてもらえますか?今私は、約束事の外にオブジェクト配列を取得する方法を見つけることができなかったので、私は私のクラスの作成と機能を私のサービスの約束で実装しています。私は本当に強い疑いを持っています。これは悪い考えです。あなたがそれを修正する方法を私に教えてもらう必要はありません。悪い習慣であるかどうか私に知らせてください;) – Jleibham

+1

@Jleibham - 私はあなたの他の質問を理解していません。あなたがそれについて助けが必要な場合は、新しい質問を投稿し、関連するコードを表示し、そのコードに関する特定の質問をすることをお勧めします。 – jfriend00

関連する問題