I am wondering how to do dynamic operations in Scala.js. For example, looking at the jQuery example in the tutorial, my understanding is you define the following in scala:
object TutorialApp extends JSApp {
def appendPar(msg: String) = {
jQuery("body").append("<p>" + msg + "</p>")
}
def main(): Unit = {
appendPar("Hello World")
}
}
This is all stuff that is generated statically at compile time. But I didn't see any way I could set the message parameter dynamically (eg read it from a DB).
I don't know about reading it from the DB. That is beyond the scope of this question (or you need to rephrase the question). Maybe an AJAX call or something?
But to read it from, for example, an <input>
tag, you'd do something like that:
def main(): Unit = {
val msg = jQuery("#myinput").value()
appendPar(msg)
}
(Although in this case it probably doesn't make any sense in a main method, but that's not the point.)
I mean, msg
is just a val
(so like a var
in JS but immutable). You can fetch it from any dynamic source of information as you like.
Edit:
If you want to access some data generated dynamically by the server when rendering the page, you can do so like this:
First, have your server generate the data as a global var
in a <script>
tag in the generated HTML. Something like:
<script type="text/javascript">
var mydata = {
msg: "Some text generated dynamically by the server"
}
</script>
Make sure to emit this script tag before the call to the main()
function of Scala.js!
Then, from Scala.js, you can access these data with the js.Dynamic
interface:
import scala.scalajs.js
val mydata = js.Dynamic.global.mydata
val msg = mydata.msg.asInstanceOf[String]
If your data have always a relatively static structure, it may be useful to declare yourself a facade type for them:
@JSName("mydata")
object MyData extends js.Object {
val msg: String = ???
}
Then you can access it without resorting to the Dynamic
API:
val msg = MyData.msg
Adding to (and attempting to generalize) sjrd's answer: To call a javaScriptMethod
on an object of a JavaScriptType
you first write a type facade for it:
import scala.scalajs.js
import scala.scalajs.js.annotation.JSName
@js.native
@JSName("JavaScriptType")
class MyType() extends js.Object {
def javaScriptMethod(someParam: String) = js.native
}
After that, it's a piece of cake to use the JavaScript code using Scala on the client side:
val myObject = new MyType()
myObject.javaScriptMethod("Yippie")
As a concrete example, to use Stack Overflow's Markdown converter Pagedown
in your Scala.js application you'd first create the type facade for it:
@js.native
@JSName("Markdown.Converter")
class MarkdownConverter() extends js.Object {
def makeHtml(txtUsingMarkdown: String): String = js.native
}
If you are learning Scala.js using this great tutorial project, you can declare the dependency on Pagedown
in Settings.scala
like this:
val jsDependencies = Def.setting(Seq(
"org.webjars.bower" % "pagedown" % "1.1.0" / "Markdown.Converter.js",
//...
Then you can simply do
val html = new MarkdownConverter().makeHtml("this is *nice*")
Here's another example where we call a static method of SparkMD5.
We define an object
as opposed to the class
of the previous example. Also, we can omit the @JSName
annotation since our Scala type is eponymous with the JavaScript type:
@js.native
object SparkMD5 extends js.Object {
def hash(str: String, raw: Boolean = false): String = js.native
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With