2015-09-13 8 views
6

Ich versuche mit tvOS zu spielen, und ich habe kleine Frage bezüglich der Handhabung json Anruf. Ich muss einige Daten über eine API erhalten, lassen Sie uns zum Zwecke der Prüfung sagen, dass ich auf diesen Link anzurufendenverbrauchen API JSon Anrufe über TVJS-tvOS

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

Ich habe versucht, mit einigen Änderungen diese Funktion zu nutzen

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

aber hat nicht funktioniert aus. Irgendwelche Hinweise oder Hilfe?

Wenn ich NodeJS verwenden muss, wie kann ich das tun?

Antwort

1

Haben Sie Ihre Funktion in der ‚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); 
} 

könnte sich lohnen nennen Blick auf https://mathiasbynens.be/notes/xhr-responsetype-json

4

Dies ist einer, den ich funktionierte. Es ist in vielerlei Hinsicht nicht ideal, zeigt Ihnen aber etwas, mit dem Sie anfangen können.

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

Und Sie können es mit dem folgenden Beispiel nennen:

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

Hoffnung, das hilft.

+0

hast du es in TVJS, tvOS versucht? – user3378649

+0

Ist es möglich, AngularJS in das TVML-Projekt zu integrieren? Und verwenden Sie den AngularJS $ http-Dienst, um die JSON-Daten abzurufen, und verwenden Sie dann ng-repeat, um die Vorlage zum Generieren der XML-Zeichenfolge dynamisch zu rendern? Nicht wirklich gut bei vaillia JS oder jQuery. Ich werde jemanden lieben, der direkt auf die Verwendung von AngularJS und TVOS verweist! –

+0

@HughHou Hast du herausgefunden, dass das möglich war? –

0

Wenn Sie die Anfrage auf App-Start zu nennen, fügen Sie einfach in 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); 
} 

}); }

In presenter.js fügen Sie eine Methode:

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(); 
}, 
+0

Könnten Sie bitte Ihre Antwort näher erläutern, indem Sie ein wenig mehr Beschreibung der von Ihnen bereitgestellten Lösung hinzufügen? – abarisone

+0

Wie verbrauchen Sie dann die Antwort in Ihrem Template? – Chris

2

ich dieses auf den tvOS erprobt - wirkt wie ein Zauber mit jQuery-Syntax (Grund Tests bestanden):

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

Beispielabfragen, die auf Apple TV funktionieren:

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

Ich bin auf diese Frage gestoßen, die nach acco sucht mplish das gleiche, und wurde inspiriert von @ JasonJerrett Antwort, aber fand es, weil in meinem Fall ein bisschen fehlt ich eine XML-Vorlage wie dies in Javascript gebaut bin mit:

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

Das Problem ist, dass man nicht Führen Sie die XHR-Anforderung in der Vorlage selbst aus, da die Vorlagenzeichenfolge zurückgegeben wird, bevor die XHR-Anforderung tatsächlich abgeschlossen wird (es gibt keine Möglichkeit, Daten aus einem asynchronen Callback zurückzugeben).Meine Lösung war es, die Ressourcenlader und führen Sie die XHR Anfrage dort, vor dem Aufruf der Vorlage und Weitergabe der Daten in die Template-Funktion zu ändern:

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

Dann wird die Template-Funktion muss geändert werden, um die eingehenden zu akzeptieren API-Daten als Parameter:

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