2016-07-29 16 views
4

Ich bekomme den deutschen Text eines bestimmten Schlüsselwortes (var title) und gebe es danach als HTML aus. Das funktioniert gut, aber jetzt wollte ich den englischen Text laden, wenn der deutsche Text nicht verfügbar ist. Dies funktioniert auch gut mit meinem Code:

var length = 500; 
var title = $('#title').attr('data-title'); 
var lang = 'de'; 
var url = 'https://' + lang + '.wikipedia.org/w/api.php?format=json&action=query' + 
    '&prop=extracts&exintro=&explaintext=&titles=' + title + '&redirects=0'; 

$.getJSON("http://query.yahooapis.com/v1/public/yql", 
{ 
    q: "select * from json where url=\"" + url + "\"", 
    format: "json" 
}, 
function (data) { 
    $.each(data.query.results.json.query.pages, function (key, val) { 
     var text = val['extract']; 
     console.log('lang-' + lang + '-text: ' + text); 
     if (text) { 
      text = text.replace('Siehe auch:', ''); 
     } else if (!text && lang != 'en') { 
     var url = 'https://en.wikipedia.org/w/api.php?format=json&action=query' + 
     '&prop=extracts&exintro=&explaintext=&titles=' + title + '&redirects=0'; 
     $.getJSON("http://query.yahooapis.com/v1/public/yql", 
      { 
       q: "select * from json where url=\"" + url + "\"", 
       format: "json" 
      }, 
      function (data) { 
       $.each(data.query.results.json.query.pages, function (key, val) { 
       text = val['extract']; 
       console.log('lang-en-text: ' + text); 
       }); 
      }); 
     } 
     console.log('lang-end-text: ' + text); 

     if (text) { 
      text = text.length > length ? text.substring(0, length - 3) + '...' : text; 
      $('#text').html(text); 
     } else { 
      setTimeout(function() { 
       $('#text').html('<?= __('EMPTY'); ?>'); 
      }, 1000); 
     } 

     console.log(data); 
    }); 
}); 

Aber nach dem zweiten $ .getJSON geschlossen ist, ist text wieder leer. Das bedeutet, dass

console.log ('lang-en-text:' + text);

arbeiten und gibt den korrekten englischen Text in der Konsole, aber der $ .getJSON die Variable text mehr hat keinen Wert nach dem Schließen, was ich mit dem Ausgang in der Konsole bestätigen kann:

console.log ('lang-end-text:' + Text);

Wie kann ich den Wert behalten? Gibt es auch eine bessere Möglichkeit zu überprüfen, ob der bestimmte Inhalt, den ich erhalten möchte (der Text in diesem Fall) ist BEFORE, so muss ich nicht zwei $.getJSON Anfragen machen? Oder ist mein Weg der richtige Weg?

EDIT: Es funktioniert jetzt!

Ich fand die Lösung dank moopet und verwendet .done und eine neue Funktion namens .setText, um den Text festzulegen. Vielleicht hilft das auch anderen, da die Frage oft aufgeputscht wird. Das ist mein Code jetzt:

var length = 500; 
var title = $('#title').attr('data-title'); 
var lang = 'de'; 
var url = 'https://' + lang + '.wikipedia.org/w/api.php?format=json&action=query' + 
    '&prop=extracts&exintro=&explaintext=&titles=' + title + '&redirects=0'; 

    $.getJSON("http://query.yahooapis.com/v1/public/yql", 
    { 
     q: "select * from json where url=\"" + url + "\"", 
     format: "json" 
    }, 
     function (data) { 
      $.each(data.query.results.json.query.pages, function (key, val) { 
       var text = val['extract']; 
       console.log('lang-' + lang + '-text: ' + text); 
       if (text) { 
        text = text.replace('Siehe auch:', ''); 
       } else if (!text && lang != 'en') { 
       var url = 'https://en.wikipedia.org/w/api.php?format=json&action=query' + 
       '&prop=extracts&exintro=&explaintext=&titles=' + title + '&redirects=0'; 
       $.getJSON("http://query.yahooapis.com/v1/public/yql", 
        { 
         q: "select * from json where url=\"" + url + "\"", 
         format: "json" 
        }, 
        function (data) { 
         $.each(data.query.results.json.query.pages, function (key, val) { 
         text = val['extract']; 
         console.log('lang-en-text: ' + text); 
         }); 
        }).done(function() { 
         setText(text); 
        }); 
       } 
       console.log(data); 
      }); 
     }).done(function() { 
      setText(text); 
     }); 

     function setText(text) { 
      if (text) { 
       text = text.length > length ? text.substring(0, length - 3) + '...' : text; 
       $('#text').html(text); 
      } else { 
       $('#text').html('Text not available.'); 
      } 
     } 
+0

Es scheint kein Fehler im Code, wie es in meiner Konsole perfekt funktioniert. –

+0

Wenn Sie dies mit HTML versuchen, wird es nicht funktionieren. Wie ich schon sagte, bekomme ich die Textausgabe in meiner Konsole, aber nach dem zweiten getJSON ist die Textvariable an dem Teil wieder leer, an dem ich meinen Text ausgeben möchte mit '$ ('# text') .html (text);' . So wird 'text' gleich nach dem Schließen des zweiten getJSON leer. – AlexioVay

+0

@Fels Dies ist nur für mich zu überprüfen, meine Konsole Log-Ausgabe und an welcher Position welcher Wert zu "Text" zugewiesen ist und es ist keine Variable. Die Variable 'text' bleibt gleich. – AlexioVay

Antwort

1

Sie sind in Konflikt mit asynchronen Javascript-Aufrufe.

Ihr Erfolg Rückruf:

function (data) { 
    $.each(data.query.results.json.query.pages, function (key, val) { 
     text = val['extract']; 
     console.log('lang-en-text: ' + text); 
    }); 
}); 

genannt wird asynchron. Mit anderen Worten, es wird zurückgestellt, bis die HTTP-Anfrage beendet ist.

Ihre

console.log('lang-end-text: ' + text); 

wird sofort aufgerufen, bevor Text zugeordnet ist, denn das ist, wie die Ausführung fortschreitet. Wenn Sie den Code für Dinge, die Sie mit dem Text innerhalb der Callback-Funktion tun möchten, werden Sie die gewünschten Ergebnisse erhalten.

+0

Oh, richtig, also sollte ich ein setTimeout verwenden, um zu prüfen, ob dem Text ein Wert zugewiesen ist? – AlexioVay

+0

Ich habe gerade Ihren Vorschlag gelesen und bearbeitet. Aber wenn ich den Code hineinlege, hat das keinen Einfluss auf den Fall, wenn die Sprache Deutsch ist, nur wenn es Englisch ist (der "else if" -Fall). – AlexioVay

+0

Verwenden Sie nicht setTimeout. Sie werden am Ende eine Umfrage durchführen, was eine Verschwendung ist, oder Sie werden am Ende zu früh feuern und die Antwort verpassen. Sie können eine andere Funktion aus dem Rückruf aufrufen, vergessen Sie nicht, oder Sie können beide Rückrufe die gleiche Funktion einstellen. Am einfachsten wäre es, eine Funktion namens "doSomethingCoolWithText()" zu erstellen, die den Parameter "text" verwendet und sie aus beiden Callbacks aufruft. – moopet