scalajs是将scala编译成js的编译器,目的在于使用scala的众多类库和强类型特征构建出稳定可扩展的js应用。build.sbt
构建文件如下:
enablePlugins(ScalaJSPlugin)name := """scalajs"""version := "1.0"scalaVersion := "2.12.1"libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "0.9.1"libraryDependencies += "be.doeraene" %%% "scalajs-jquery" % "0.9.1"libraryDependencies += "com.lihaoyi" %%% "scalatags" % "0.6.2"libraryDependencies += "com.thoughtworks.binding" %%% "dom" % "latest.release"libraryDependencies += "com.thoughtworks.binding" %%% "binding" % "latest.release"libraryDependencies += "com.thoughtworks.binding" %%% "futurebinding" % "latest.release"addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
project/plugins.sbt
配置如下:
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "0.6.14")addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0")
本demo额外使用scalatags
库作为辅助。
scala部分
package webappimport org.scalajs.dom.htmlimport scalatags.JsDom.all._import scala.scalajs.js.JSAppimport scala.scalajs.js.annotation.JSExport/** ?* Created by nathan on 17/3/20. ?*/object TutorialApp extends JSApp{ ?def main():Unit ={ ?} ?@JSExport ?def test(target:html.Div):Unit={ ???val name=("蒋航","hangscer") ???val d = div( ?????h1("Hello World!",color:="blue",fontFamily:="Monaco",fontSize:="14px"), ?????p(s"my name is ${name._1}"), ?????p(s"also,call me ${name._2}") ???).render ???target.appendChild(d) ?}}
在sbt
中使用fastOptJS
命令编译后,html部分引用该js文件即可。
<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<title>Titlehah</title> ???<script type="text/javascript" src="jquery.js"></script> ???<script type="text/javascript" src="../target/scala-2.12/scalajs-fastopt.js"></script></head><body> ???<div id="test_div_id"> ???</div><script type="text/javascript"> ?webapp.TutorialApp().test(document.getElementById("test_div_id"))</script></body></html>
@JSExport
注解目的在于在<script></script>
标签中,原生js向scalajs
中传參。
接下来这个例子是在去除某个list:List[Int]
中相同的元素,去重算法。
package clientjsimport scala.scalajs.js.JSAppimport scala.scalajs.js.annotation.JSExport/** ?* Created by nathan on 17/3/20. ?*/object TutorialApp extends JSApp{ ?def main():Unit={ ???val list=qsort(List(1,2,1,34,45,4562,2131,34,324,435,34,21312,34,345435,34,242321,1)) ???println(list) ???println(deMulti(list)) ?} ?def qsort(list:List[Int]):List[Int]=list match { ???case h::t=>qsort(t.filter(i=>i<h))++List(h)++qsort(t.filter(i=>i>=h)) ???case Nil=>Nil ?} ?def deMulti(list: List[Int]):List[Int]=list match { ???case Nil=>Nil ???case h::Nil=>List(h) ???case h::t=> ?????if(h==t.head) ???????deMulti(t) ?????else ???????List(h)++deMulti(t) ?}}
开启scalatra
后,在浏览器console中结果如下:
<script src="./public/javascripts/scalajs/my-scalatra-web-app-fastopt.js" type="text/javascript"> ???clientjs.TutorialApp().main()</script>
需要将编译后的js文件引用html中。
演示ajax功能,本demo使用scalatra作为服务器,
//web服务器设置如下class ScalatraBootstrap extends LifeCycle { ?override def init(context: ServletContext) { ???context.mount(new HiScalatraServlet,"/") ?}}class HiScalatraServlet extends ScalatraServlet{ ?before("/hello"){ ???format_=("json") ?} ?//http://127.0.0.1:8080/hello ?get("/hello"){ ???"""{"a":21312,"b":3243242}""" ?}}
//scalajspackage clientjsimport scala.scalajs.js.JSAppimport scala.scalajs.js.annotation.JSExport/** ?* Created by nathan on 17/3/20. ?*/object TutorialApp extends JSApp{ ?@JSExport ?def funAjax():Unit={ ???import org.scalajs.jquery._ ???jQuery.get(url = "http://127.0.0.1:8080/hello",success = (data:Any)=>println("****"+data)) ?}}
jQuery
功能需要在html引用jquery.js
文件。
html部分如下:
<script type="text/javascript" src="./public/javascripts/jquery.js"></script><script src="./public/javascripts/scalajs/my-scalatra-web-app-fastopt.js" type="text/javascript"></script><script type="text/javascript"> ???//页面一旦加载,立即发起get请求 ???clientjs.TutorialApp().funAjax()</script>
结果如下: