我试图在scala-js应用中使用firebase。 我正在努力将firebase-result转换为scala。
我使用了明确类型的repo的firebase.d.ts文件来创建scala-classes。通过一些调整,它到目前为止工作正常。
我使用此示例代码从firebase sample-repository中获取一些数据:
<html>
<head>
<script src='https://cdn.firebase.com/js/client/2.2.1/firebase.js'></script>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'></script>
</head>
<body>
<script>
var myDataRef = new Firebase('https://gjauaudjwdc.firebaseio-demo.com/');
myDataRef.on('value', function (snapshot) {
console.log(" received value: ", snapshot.val());
console.log("toString'ed value: ", snapshot.val().toString());
});
</script>
</body>
</html>
日志正确记录收到的快照(json-object)。
received value: Object {-ImBnHMmOnndxre8XSkl: Object, -ImBnI0WLch7L7ndl6Qd: Object}
toString'ed value: [object Object]
这是scala-js-version
package example
import de.flwi.firebase._
import scala.scalajs.js
object ScalaJSExample extends js.JSApp {
def main(): Unit = {
val rootRef: Firebase = FirebaseFactory.create("https://gjauaudjwdc.firebaseio-demo.com/")
rootRef.on1("value", callback = { (snapshot: FirebaseDataSnapshot) => {
println(snapshot.value())
}
})
}
}
当我使用scala-js的Firebase-wrapper尝试相同的操作时,我只会将[object Object]
写入控制台。就像在第一个例子中对接收到的值调用toString()时一样。
相应的特征看起来像这样(缩短):
trait FirebaseDataSnapshot extends js.Object {
@JSName("val") def value(): js.Dynamic = js.native
}
trait FirebaseQuery extends js.Object {
@JSName("on") def on1(eventType: String, callback: js.Function1[FirebaseDataSnapshot, Unit], cancelCallback: js.Function1[js.Any, Unit] = ???, context: Object = ???): js.Function1[FirebaseDataSnapshot, Unit] = js.native
@JSName("on") def on2(eventType: String, callback: js.Function2[FirebaseDataSnapshot, String, Unit], cancelCallback: js.Function1[js.Any, Unit] = ???, context: Object = ???): js.Function2[FirebaseDataSnapshot, String, Unit] = js.native
}
@JSName("Firebase")
trait Firebase extends FirebaseQuery {
}
import scala.scalajs.js.Dynamic.{global => g, newInstance => jsnew}
@JSName("Firebase")
object FirebaseFactory {
def create(url: String): Firebase = jsnew(g.Firebase)(url).asInstanceOf[Firebase]
}
有没有人能指出我正确的方向如何以正确的方式处理js.Dynamic,比如迭代jsObject的值?
我上传了project to github两个例子(index-with-js.html和index.fastopt.html)
答案 0 :(得分:0)
我建议将对象解释为js.Dictionary
:
trait FirebaseDataSnapshot extends js.Object {
@JSName("val") def value(): js.Dictionary[js.Any] = js.native
}
js.Dictionary
拥有scala.Map
的所有方法(隐式添加)。所以你现在可以简单地写一个for循环(或调用get
):
rootRef.on1("value", callback = { (snapshot: FirebaseDataSnapshot) => {
// iterate over key value pairs
for ((key, value) <- snapshot) println(key)
// get a particular key
snapshot.get("foo") // returns an Option
}
})
答案 1 :(得分:0)
@ gzmo的答案在一般情况下是正确的。但是如果你知道返回对象的结构是什么(我不知道Firebase,但是数据库调用通常也是如此 - 你确切知道应该在结果中定义哪些字段) ,您可以为结果定义外观特征,并使用asInstanceOf []将快照投射到该特征。我可能建议将其作为一种更强类型的方法,如果结果字段相当一致:外观通常更容易在Scala代码中使用。
这些答案不是/或 - 例如,您可以将其视为字典用于记录目的,然后将其转换为外观,然后再将其交给更高级别的代码。