2016-07-17 3 views
1

Ich bin neu in scala.js und ein paar Probleme mit meinem Kopf um ihn herum. Derzeit bin ich mit dem folgenden stecken (der Nicht-Asynchron-Flag ist beabsichtigt):scala.js: map ein JSON-Array geladen über jQuery

val req = jQuery.ajax(literal(
    url = ..., 
    `type` = "GET", 
    async = false).asInstanceOf[JQueryAjaxSettings] 
) 
val res = req.selectDynamic("responseText").toString 

Eigentlich ist die Antwort ein JSON-Array ist. Jedes Element im Array hat ein Feld namens name (neben anderen Feldern), dies ist garantiert und muss nicht validiert werden. Was ich tun möchte, ist .map jeder Eintrag in seinem Namensfeld, so dass die resultierende Ausgabe ist ein Array[String] enthält nur die Namen der Elemente. Wie kann ich das erreichen?

Antwort

2

Hmm. Beachten Sie, dass das Async-Flag längst veraltet ist. Ich hatte nicht bemerkt, dass es überhaupt noch verfügbar war. Aber wenn man das liest, dann ist das grob gesagt. (Offensichtlich ungetestet; passen Sie es an die Realität Ihrer Situation an.)

Mein Eindruck von Ihrer Beschreibung ist, dass das Ergebnis eine JSON-Zeichenfolge ist, die tatsächlich ein Array codiert. Wenn das der Fall, ist der erste Schritt, das analysieren:

val rawArray:js.Dynamic = JSON.parse(res) 

dass der JSON-String parst, und gibt Ihnen ein js.Dynamic, die die „rohe“ Form eines JS-Objekts ist. Zu diesem Zeitpunkt weiß Scala.js nichts über seine Struktur.

Als nächstes sollten Sie Scala.js beschreiben, was die Struktur jedes Element Ihres Arrays wie folgt aussieht:

@js.native 
trait MyStruct extends js.Object { 
    val name:String = js.native 
} 

Dies ist, wie Sie Scala.js über einen JavaScript-Typ anweisen. Sie sagen es, dass dieser Typ eine Eigenschaft namens "name" hat, die eine Zeichenfolge ist. Sie können die anderen Felder des Typs hinzufügen oder nicht, wie Sie bevorzugen - da es so klingt, als ob Sie nur name interessieren, müssen Sie den Rest nicht auflisten.

Dann sagen Sie Scala.js was Ihr rawArray wirklich ist:

val myArray = rawArray.asInstanceOf[js.Array[MyStruct]] 

asInstanceOf nicht Änderung nichts - es ist einfach zu Scala.js erklärte: „Ich weiß, dass diese js. Dynamic ist eigentlich ein Array von MyStruct ". So, jetzt haben Sie myArray, die ein js.Array[MyStruct] ist, und Sie können map als normal verwenden:

val myNames = myArray.map(_.name) 

Diese Art von Sachen ist ziemlich normal, wenn Sie an der Grenze von Scala.js und roh JavaScript arbeiten. Da die JS-Ebene vollständig untypisiert ist und die SJS-Ebene stark typisiert ist, müssen Sie SJS "beibringen", was die tatsächlichen Typen sind, die aus der JS-Ebene kommen. Dann kannst du einfach diese Typen im Rest des SJS-Codes annehmen ...

+0

Danke, das sieht vielversprechend aus. Ich bin im Moment beschäftigt, werde es aber in den nächsten Tagen noch einmal anschauen. – ceran

+0

Funktioniert perfekt, danke – ceran