【问题标题】:consuming API JSon calls through TVJS-tvOS通过 TVJS-tvOS 使用 API JSON 调用
【发布时间】:2015-12-09 19:07:08
【问题描述】:

我正在尝试使用 tvOS,但我对处理 json 调用有一个小问题。我必须通过 API 获取一些数据,假设为了测试,我正在调用此链接

http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%223015%22&format=json

我尝试通过一些修改来使用这个功能

function getDocument(url) {
  var templateXHR = new XMLHttpRequest();
  templateXHR.responseType = "json";
  templateXHR.open("GET", url, true);
  templateXHR.send();
  return templateXHR;
}

但没有成功。任何提示或帮助?

如果我需要使用 NodeJS,我该怎么做?

【问题讨论】:

    标签: javascript node.js xcode api tvos


    【解决方案1】:

    您是否在“App.onLaunch”中调用了您的函数

    App.onLaunch = function(options) {
      var url = 'http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%223015%22&format=json';
      var doc = getDocument(url);
      console.log(doc);
    }
    

    可能值得关注https://mathiasbynens.be/notes/xhr-responsetype-json

    【讨论】:

      【解决方案2】:

      您需要在 XHR 对象上实现onreadystatechange 事件来处理响应:

      templateXHR.onreadystatechange = function() {
        var status;
        var data;
        if (templateXHR.readyState == 4) { //request finished and response is ready
          status = templateXHR.status;
          if (status == 200) {
            data = JSON.parse(templateXHR.responseText);
            // pass the data to a handler
          } else {
            // handle the error
          }
        }
      };
      

      【讨论】:

        【解决方案3】:

        这是我开始工作的。它在许多方面并不理想,但可以让您开始使用。

        function jsonRequest(options) {
        
          var url = options.url;
          var method = options.method || 'GET';
          var headers = options.headers || {} ;
          var body = options.body || '';
          var callback = options.callback || function(err, data) {
            console.error("options.callback was missing for this request");
          };
        
          if (!url) {
            throw 'loadURL requires a url argument';
          }
        
          var xhr = new XMLHttpRequest();
          xhr.responseType = 'json';
          xhr.onreadystatechange = function() {
            try {
              if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                  callback(null, JSON.parse(xhr.responseText));
                } else {
                  callback(new Error("Error [" + xhr.status + "] making http request: " + url));
                }
              }
            } catch (err) {
              console.error('Aborting request ' + url + '. Error: ' + err);
              xhr.abort();
              callback(new Error("Error making request to: " + url + " error: " + err));
            }
          };
        
          xhr.open(method, url, true);
        
          Object.keys(headers).forEach(function(key) {
            xhr.setRequestHeader(key, headers[key]);
          });
        
          xhr.send();
        
          return xhr;
        }
        

        你可以用下面的例子来调用它:

        jsonRequest({
          url: 'https://api.github.com/users/staxmanade/repos',
          callback: function(err, data) {
            console.log(JSON.stringify(data[0], null, ' '));
          }
        });
        

        希望这会有所帮助。

        【讨论】:

        • 您在 TVJS、tvOS 中尝试过吗?
        • 是否可以将 AngularJS 集成到 TVML 项目中。并使用AngularJS $http服务获取json数据然后使用ng-repeat动态渲染模板生成xml字符串?不太擅长 vaillia JS 或 jQuery。会喜欢有人指出一起使用 AngularJS 和 TVOS 的直接方法!
        • @HughHou 你认为这是可能的吗?
        【解决方案4】:

        如果您想在应用启动时调用请求,只需添加 application.js:

        App.onLaunch = function(options) {
          var javascriptFiles = [
            `${options.BASEURL}js/resourceLoader.js`, 
            `${options.BASEURL}js/presenter.js`
          ];
        
        evaluateScripts(javascriptFiles, function(success) {
         if(success) {
          resourceLoader = new ResourceLoader(options.BASEURL);
          var index = resourceLoader.loadResource(`${options.BASEURL}templates/weatherTemplate.xml.js`, function(resource) {
        
            var doc = Presenter.makeDocument(resource);
        
            doc.addEventListener("select", Presenter.load.bind(Presenter));
        
            doc.addEventListener('load', Presenter.request);
        
            navigationDocument.pushDocument(doc);
        
          });
        } else {
          var errorDoc = createAlert("Evaluate Scripts Error", "Error attempting to evaluate external JavaScript files.");
          navigationDocument.presentModal(errorDoc);
        }
        

        }); }

        在presenter.js中添加一个方法:

        request: function() {
        
          var xmlhttp = new XMLHttpRequest() , method = 'GET' , url = 'your Api url';
          xmlhttp.open( method , url , true );
          xmlhttp.onreadystatechange = function () {
            var status;
            var data;
            if (xmlhttp.readyState == 4) {
              status = xmlhttp.status;
              if (status == 200) {
                data = JSON.parse(xmlhttp.responseText);
                console.log(data);
              } else {
                var errorDoc = createAlert("Evaluate Scripts Error", "Error attempting to evaluate external JavaScript files.");
                navigationDocument.presentModal(errorDoc);
              }
            }
          };
          xmlhttp.send();
        },
        

        【讨论】:

        • 能否请您详细说明您的答案,添加更多关于您提供的解决方案的描述?
        • 你如何在你的模板中使用响应?
        【解决方案5】:

        我在 tvOS 上测试了这个 - 就像 jQuery 语法的魅力一样(基本测试通过):

        var $ = {};
        $.ajax = function(options) {
        
          var url = options.url;
          var type = options.type || 'GET';
          var headers = options.headers || {} ;
          var body = options.data || null;
          var timeout = options.timeout || null;
          var success = options.success || function(err, data) {
            console.log("options.success was missing for this request");
          };
          var contentType = options.contentType || 'application/json';
          var error = options.error || function(err, data) {
            console.log("options.error was missing for this request");
          };
        
          if (!url) {
            throw 'loadURL requires a url argument';
          }
        
          var xhr = new XMLHttpRequest();
          xhr.responseType = 'json';
          xhr.timeout = timeout;
          xhr.onreadystatechange = function() {
            try {
              if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    if (xhr.responseType === 'json') {
                        success(null, xhr.response);
                    } else {
                        success(null, JSON.parse(xhr.responseText));
                    }
                } else {
                  success(new Error("Error [" + xhr.status + "] making http request: " + url));
                }
              }
            } catch (err) {
              console.error('Aborting request ' + url + '. Error: ' + err);
              xhr.abort();
              error(new Error("Error making request to: " + url + " error: " + err));
            }
          };
        
          xhr.open(type, url, true);
        
          xhr.setRequestHeader("Content-Type", contentType);
          xhr.setRequestHeader("Accept", 'application/json, text/javascript, */*');
        
          Object.keys(headers).forEach(function(key) {
            xhr.setRequestHeader(key, headers[key]);
          });
        
          if(!body) {
            xhr.send();
            } else {
                xhr.send(body);
            }
        
          return xhr;
        }
        

        在 Apple TV 上运行的示例查询:

        var testPut = function(){
        
            $.ajax({
                type: 'PUT',
                url: url,
                success: successFunc,
                error: errFunc,
                dataType: 'json',
                contentType: 'application/json',
                data: data2
            });
        }
        var testGet = function(){
            $.ajax({
                dataType: 'json',
                url: url,
                success: successFunc,
                error: errFunc,
                timeout: 2000
            });
        
        }
        
        var getLarge = function(){
            $.ajax({
                dataType: 'json',
                url: url,
                success: successFunc,
                error: errFunc,
                timeout: 2000
            });
        }
        

        【讨论】:

          【解决方案6】:

          我遇到了这个问题,希望完成同样的事情,并受到@JasonJerrett 的回答的启发,但发现它有点缺乏,因为在我的实例中,我使用的是这样的 Javascript 内置的 XML 模板:

          // Index.xml.js
          var Template = function() { 
            return `very long xml string`;
          };
          

          问题是您无法在模板本身内部执行 XHR 请求,因为模板字符串将在 XHR 请求实际完成之前返回(无法从异步回调内部返回数据)。我的解决方案是在调用模板并将数据传递到模板函数之前,修改资源加载器并执行 XHR 请求那里

          ResourceLoader.prototype.loadResource = function(resource, dataEndpoint, callback) {
              var self = this;
              evaluateScripts([resource], function(success) {
                  if (success) {
                      // Here's the magic. Perform the API call and once it's complete,
                      // call template constructor and pass in API data
                      self.getJSON(dataEndpoint, function(data) {
                          var resource = Template.call(self, data);
                          callback.call(self, resource);
                      });
                  } else {
                      var title = "Failed to load resources",
                          description = `There was an error attempting to load the resource. \n\n Please try again later.`,
                          alert = createAlert(title, description);
          
                      Presenter.removeLoadingIndicator();
          
                      navigationDocument.presentModal(alert);
                  }
              });
          }
          
          // From: https://mathiasbynens.be/notes/xhr-responsetype-json
          ResourceLoader.prototype.getJSON = function(url, successHandler, errorHandler) {
            var xhr = new XMLHttpRequest();
            xhr.open('get', url, true);
            xhr.onreadystatechange = function() {
              var status;
              var data;
              if (xhr.readyState == 4) { 
                status = xhr.status;
                if (status == 200) {
                  data = JSON.parse(xhr.responseText);
                  successHandler && successHandler(data);
                } else {
                  errorHandler && errorHandler(status);
                }
              }
            };
            xhr.send();
          };
          

          然后需要修改模板函数以接受传入的API数据作为参数:

          // Index.xml.js
          var Template = function(data) { 
              return 'really long xml string with injected ${data}';
          };
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-03-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多