2017-01-15 6 views
0

私はTVML/TVJSアプリで作業しています.Javascriptでクラスを操作するときに問題が発生しました。コールバックの実行時にJSクラス内の関数へのアクセスが失われる

class ResourceLoader { 

getHomeScreen() { 
    var homeData = BASEURL + "/home.json"; 
    var homeTemplate = BASEURL + "/home.tvml"; 

    this.getRemoteJSON(homeData, homeTemplate, this._jsonLoaded); 
} 

_jsonLoaded(template, jsonString) { 
    var parsedJSON = JSON.parse(jsonString); 
    this.getRemoteXMLFile(template, parsedJSON); 
} 

getRemoteJSON(file, template, callback) { 
    var xhr = new XMLHttpRequest(); 
    xhr.responseType = "text"; 
    xhr.addEventListener("load", function() { 
     callback(template, xhr.responseText); 
    }, false); 
    xhr.open("GET", file, true); 
    xhr.send(); 
} 

getRemoteXMLFile(template, json) { 
    var xhr = new XMLHttpRequest(); 
    xhr.responseType = "xml"; 
    xhr.addEventListener("load", function() { 
     loadRemoteFile(xhr.responseText, json); 
    }, false); 
    xhr.open("GET", template, true); 
    xhr.send(); 
} 

} 

(BASEURLは、アプリケーションで定義されたグローバル変数です:

マイ開始application.jsファイルには、私は次のようにResourceLoader.jsと呼ばれる別のファイルを持っている機能

resourceLoader = new ResourceLoader(); 
resourceLoader.getHomeScreen(); 

呼び出します。 js)

最初はすべてうまく動作します。 getHomeScreen()が呼び出されると、getRemoteJSON()を呼び出し、_jsonLoaded()をコールバックとして渡します。 getRemoteJSONはAJAX呼び出しを行い、コールバックを実行します。ここで問題が発生します。一度_jsonLoadedの中で "this"が定義されていないので、this.getRemoteXMLFileを呼び出すと、 "未定義はオブジェクトではありません(this.getRemoteXMLFile 'を評価しています)"

なぜgetHomeScreen ()ではなく、_jsonLoaded()ではありませんか? _jsonLoaded()からgetRemoteXMLFile関数にアクセスするにはどうすればよいですか?

ありがとうございました。

答えて

0

これは、コールバックが関数ではないためです。

良い解決策は、ES6 Promisesを使用することです。

ここで約束

getJson(url) { 
    return new Promise(
     (resolve, reject) => { 
      this.get(url).then(
       (value) => { 
        resolve(JSON.parse(value)); 
       }, 
       function (reason) { 
        console.error(reason); 
        reject(new Error(reason)); 
       } 
      ) 
     } 
    ) 
} 

そして、どのように "これは" _jsonLoadedに(getHomeScreenでの作業)が、いなかったのはなぜ(

getJson('http://jsonplaceholder.typicode.com/posts/1').then(
    (value) => { 
     console.log(value); 
    }, 
    function (reason) { 
     console.error(reason); 
    } 
); 
0

それを呼び出すためにAJAXを使用してデータを取り出す例です)? _jsonLoaded()からgetRemoteXMLFile関数にアクセスするにはどうすればよいですか?

これは技術的にはTVMLアプリに固有のものではありませんが、JSの一般的な質問の詳細なので、JavaScriptの観点からthis(意図しない)と答えさせてください。

getHomeScreenを呼び出すと、オブジェクトインスタンスresourceLoader.getHomeScreen()で呼び出されるため、thisのコンテキストが保持されます。しかし、_jsonLoaded関数を関数のコールバック引数として渡してcallback(template, xhr.responseText)を実行すると、オブジェクトコンテキストが失われます。

純粋なOOP言語の背景を持つ人物のために、最近導入されたJavaScript classキーワードmight be confusingは、オブジェクト指向の継承ではなく、JavaScriptの古くからのプロトタイプの継承に対する文法的な砂糖です。したがって、同じグループに所属する場合は、その違いを理解することをお勧めします。gotchas

あなたの即時の問題のステートメントへの簡単で簡単な解決策は、コールバックとして関数を渡すたびにbindthisコンテキストになることです。

this.getRemoteJSON(homeData, homeTemplate, this._jsonLoaded.bind(this)); 

サイドノート:あなたはTVMLアプリケーションを構築するためのフレームワークatvjsを試してみましたか?それは、従来のTVMLアプリの基本的な煩雑さと複雑さを抽象化して、ノイズをあまり使わずにアプリケーションを構築し、素早く試作することができます。

関連する問題