0

我正在开发一个 TVML/TVJS 应用程序,并且在使用 Javascript 中的类时遇到了问题。

我的起始 application.js 文件调用了一个函数

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

我有一个名为 ResourceLoader.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 中定义的全局变量)

一开始一切正常。getHomeScreen() 被调用,它设法调用 getRemoteJSON() 并将 _jsonLoaded() 作为回调传递。getRemoteJSON 执行 AJAX 调用,然后运行回调。这就是问题发生的地方。一旦进入 _jsonLoaded,“this”就变为未定义,因此当我调用 this.getRemoteXMLFile 时,我收到错误消息“未定义不是对象(正在评估 'this.getRemoteXMLFile')”

为什么“this”在 getHomeScreen() 中有效,但在 _jsonLoaded() 中无效?如何从 _jsonLoaded() 访问我的 getRemoteXMLFile 函数?

谢谢你的帮助。

4

2 回答 2

0

那是因为回调不是一个函数。

一个好的解决方案是使用 ES6 Promises。

这是一个使用带有 Promise 的 AJAX 获取数据的示例

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

以及如何称呼它

getJson('http://jsonplaceholder.typicode.com/posts/1').then(
    (value) => {
        console.log(value);
    },
    function (reason) {
        console.error(reason);
    }
);
于 2017-01-15T16:14:45.093 回答
0

为什么“this”在 getHomeScreen() 中有效,但在 _jsonLoaded() 中无效?如何从 _jsonLoaded() 访问我的 getRemoteXMLFile 函数?

它在技术上并不特定于 TVML 应用程序,而是更多的一般 JS 问题,所以让我this根据 JavaScript 回答(不是双关语)。

当您调用时,getHomeScreen您在对象实例上调用它resourceLoader.getHomeScreen(),因此this上下文被保留。但是,当您将_jsonLoaded函数作为函数的回调参数传递并执行callback(template, xhr.responseText)时,对象上下文就会丢失。

最近引入的 JavaScriptclass关键字可能会让纯 OOP 语言背景的人感到困惑,因为它不是面向对象的继承,而仅仅是 JavaScript 中古老的原型继承的语法糖。因此,如果碰巧属于同一组,建议了解差异和陷阱

话虽如此,当您将函数作为回调传递时,对您的直接问题陈述的一个直接而简单的解决方案是bind上下文。this

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

旁注:您是否尝试过使用 atvjs框架来构建 TVML 应用程序?它可以让您在没有太多噪音的情况下构建和快速原型化应用程序,从而抽象出传统 TVML 应用程序的底层麻烦和复杂性。

于 2017-06-29T17:45:21.333 回答