æè¿Scala.jsã®è©±ãããã¨çµæ§ãªäººãRTãã¦ããããTypeScriptã®ä»ã«AltJSã«ã¯ä»ã©ããªã®ãããã®ããªãã¨ãã話ã«å¼ç¨RTã§Scala.jsä»ã¢ããã§ããã¨ãã話ããããçµæ§ã¦ã±ããä¸éçã«ã¯TypeScript alternativeã«èå³ããã人ãå¤ãããã ãä¸æ¹ããããã«æ®ã£ã¦ããScala.jsæ å ±ã¯æ°å¹´åã®ãã®ãå¤ãããã§ããã¾ãç©æ¥µçã«æ¥æ¬èªã§ã®æ å ±çºä¿¡ããªããã¦ããªãæ§åãããã§ãããæè¿Scala.jsã¯ã©ãããæããªã®ããããã¦ã©ãããã°å§ããããã®ãã¨ããæ å ±ãã¾ã¨ããã¨éè¦ããããããããªãã¨æããæ¸ããã¨ã«ããã
Scala.jsã¯æ°å¹´åã¾ã§ã¯ãªã¢ãã£ã¿ãããªæãã ã£ããã§ããæè¿ã¯TSã®ã©ã¤ãã©ãªããèªåã§åãçããä»çµã¿ããã£ãããã¡ããã³ãã«å°ãããªã£ããã¨ãã¡ããã¡ãé²åãã¦ã¾ã!! https://t.co/c06IZGWhYF
— Windymelt(ãããã) (@windymelt) 2023å¹´9æ29æ¥
æ³å®èªè
- Scalaã®ãã¨ã¯ã¡ãã£ã¨ç¥ã£ã¦ãããããã¯ç¥ããªã人
- TypeScriptã¨ãã£ãAltJSã®ãã¨ã¯ããç¨åº¦ç¥ã£ã¦ã人
- æè¿ã®Scala.jsã©ããªãï¼ã¨ãã人
ããããScalaã¨ã¯
TypeScriptã¯ç¥ã£ã¦ã¦ãScalaã¯ç¥ããªãã¨ãã人ããããããããªããScalaã¯ã以ä¸ã®ãããªç¹å¾´ãæã¤æ±ç¨ããã°ã©ãã³ã°è¨èªã§ãã:
- JVMã§åä½ãã
- Javaç¨ã©ã¤ãã©ãªãééçã«å©ç¨ã§ãã
- é«åº¦ãªJVMã®æé©åãå©ç¨ã§ãããããããªãéã
- ã©ãã§ãåã
- é¢æ°åè¨èªã¨ãã¦ã®ç¹å¾´ã¨ãJavaç±æ¥ã®ãªãã¸ã§ã¯ãæåã®ã¡ã«ããºã ãé«åº¦ã«çµ±åãã¦ãã
- å¿ è¦ã«å¿ãã¦é¢æ°åçãªæ¸ãæ¹ããããã¨ãå¯è½
- å¼·åãªåã·ã¹ãã ãä¿æãã
- é¢æ°åè¨èªã¨ãã¦ã®å¼·ã¿ã¯ãã®åã·ã¹ãã ã®å¼·åãã«ããã¨ããã大ãã
- åã·ã¹ãã ãå¼·åã ã¨ãåå®å ¨ãªã¾ã¾æè»ãªè¡¨ç¾åãæã«ãããã¨ãã§ãã
- åã·ã¹ãã ãå¼·åã ã¨ãæ¢ã«å®è£ ããã¦ãããã®ããæ´¾çããå®è£ ãèªåçã«ã³ã³ãã¤ã©ãå°ãã¦ããããã¨ããã
- ã³ã¬ã¯ã·ã§ã³ã¡ã½ããããããã¨å¼·å
- ããããä»ã®ã©ã®è¨èªãããå¼·å
ããç¥ãããScalaã®å©ç¨ä¾ã¨ãã¦ã¯Twitterã®ããã¯ã¨ã³ããChatworkã®ããã¯ã¨ã³ããã¯ã¦ãªããã¯ãã¼ã¯ã®ããã¯ã¨ã³ããMinecraftã®Modåºç¤ã§ããForgeãªã©ããããå ãã¦ãScalaã¢ããªã±ã¼ã·ã§ã³/ã©ã¤ãã©ãªã¨ãã¦ã¯ãåæ£ãã¼ã¿å¦çåºç¤ã§ããSparkããåæ£ã·ã¹ãã åºç¤ã§ããAkka/Pekkoãèåã§ããã
Scalaã¯ãã®å²å¦ã¨ãã¦ããã®ååã®ç±æ¥ã§ãããScalableã軸ã¨ãã¦æ®ãã¦ãããç°¡æ½ãªè¨è¿°ã§å°è¦æ¨¡ãªãã¼ã«ãã大è¦æ¨¡ãªã·ã¹ãã ã¾ã§ããµãã¼ãã§ããã
å ¸åçãªScalaã®ããã°ã©ã ã¯ä»¥ä¸ã®ãããªæãã :
println("hello, world!") // Hello world Seq(1, 2, 3, 4, 5).reduce(_ * _) // => 1 * 2 * 3 * 4 * 5 = 120 // pattern matching case class HttpResponse(status: Int, headers: Map[String, Seq[String]], body: String) val res: HttpResponse = ... res match case HttpResponse(200, _, _) => "OK!" case HttpResponse(n, _, _) if (n % 100) == 2 => "Successful!" case _ => "Not Successful!"
ã¾ããScalaã®å¼·åãªåã·ã¹ãã ã®å¨åã示ãä¾ã¨ãã¦ãCirceã©ã¤ãã©ãªã使ã£ã¦ã¯ã©ã¹ãJSONã«å¤æããæ©æ§ãå©ç¨ããæ§åãç´¹ä»ãã:
//> using scala 3.3.0 //> using dep "io.circe::circe-core:0.14.6" //> using dep "io.circe::circe-generic:0.14.6" import io.circe._, io.circe.generic.auto._, io.circe.syntax._ // ã¦ã¼ã¶ãã¼ã¿ãå ¥ããã¯ã©ã¹ãå®ç¾©ãã case class User(name: String, age: Int, address: Address) case class Address(zip: Long, line1: String, line2: String) // valã®åã¯èªåçã«æ¨è«ãããã®ã§æ¸ããªãã¦ãã val me = User("Windymelt", 30, Address(1234567, "line1", "line2")) println(me.asJson.noSpaces)
ãããå®è¡ããã¨{"name":"Windymelt","age":30,"address":{"zip":1234567,"line1":"line1","line2":"line2"}}
ãåºåããããä¸è¦ä½ã®å¤å²ããªãJSONæä½ã ãã ä¸è¬çãªã¹ã¯ãªããè¨èªã¨æ¯ã¹ã¦ãJSONã«å¤æã§ãããã©ãããã³ã³ãã¤ã«æã«ä¿è¨¼ãããã¨ããéããããã ãããã£ã¦ã³ã³ãã¤ã«ããæåããã°å®è¡æã«å¤æã«å¤±æãã¦ã¨ã©ã¼ãèµ·ããã¨ãããã¨ãç¡ãã¨ãã大ããªã¡ãªãããããããããã¼ã¿ãJSONã«å¤æã§ãããã¨ã確å®ããªãéãã³ã³ãã¤ã«ãéããªãä»çµã¿ã«ãªã£ã¦ããããã ããã®æ¤æ»ã¯åã¬ãã«ã§è¡ãããã
ãããã£ãã³ã³ãã¤ã«æã«æ°ã ã®åä½ãä¿è¨¼ã§ããç¹å¾´ã«ãããScalaã§ã¯ãã¹ãã³ã¼ãã®éã大ããæ¸ãããã¨ãå¯è½ã ãå®è¡æã«typoãåå ã§å¤±æããã¨ãããã¹ã極éã¾ã§æ¸ããè¨è¨ãå¯è½ã§ãããããã¯ã³ã¼ãã£ã³ã°æã®å®å¿æã«ç´æ¥ã¤ãªããã
Scala.jsã¨ã¯
Scala.jsã¯ScalaãJavaScriptã«ãã©ã³ã¹ãã¤ã«ãã¦ãã©ã¦ã¶ä¸ã§å®è¡ãããã¨ããããã¸ã§ã¯ãã§ãããScalaã®ãµãã»ãããä½ã£ã¦ãããå®è¡ã§ããããè¨èªãä½ãã®ã§ã¯ãªããããã¾ã§æ¬ç©ã®ScalaãJavaScriptã«ãã©ã³ã¹ãã¤ã«ããç¹ã«ç¹è²ãããããã®ãããScalaç¨ã©ã¤ãã©ãªã®ãã¡å¤ãããã®ã¾ã¾Scala.jsã§ãå©ç¨ã§ããã¨ããå¼·åãªã¡ãªãããæ±ãã¦ããä¸æ¹ã§ãTypeScriptãJavaScriptã§å©ç¨ããã¦ããã©ã¤ãã©ãªããã®ã¾ã¾å¼ã¶ãã¨ãã§ããä»çµã¿ãç¨æããã¦ãããæ¢åã®è³ç£ã®æå¹æ´»ç¨ãå¯è½ã§ããã
Scala.jsã¯ãTypeScriptã¨æ¯ã¹ãã¨ä»¥ä¸ã®ãããªç¹å¾´ãæã¤:
- æ¢åã®JavaScriptã«åãä»ããTypeScriptã¨æ¯ã¹ãã¨ãScala.jsã¯æåããScalaã®åã·ã¹ãã ãå©ç¨ããã®ã§ããªãç´ ç´ãªæ¯èãããã
- å°é·ã®å°ãªãã«ã¤ãªãã
- Scalaã®ãããã¦è±å¯ãªã³ã¬ã¯ã·ã§ã³ã¡ã½ããã使ãã
- ã³ã¬ã¯ã·ã§ã³ã©ã¤ãã©ãªã®åçºæãããªãã¦ãè¯ã
- ããªããæåãªå°é·ãã¿ãããªè¦ç´ ããªã
- é¢é£ãã¼ã«ãã·ã³ãã«
- ãã¼ã¸ã§ã³ãã¡ãã£ã¨å¤ãã£ã¦ãã«ããã¤ãã©ã¤ã³ãã©ãã©ãå£ããã¨ãããã¨ããªã
- Scalaã¯ãã«ããã¼ã«ã®åºæ¥ãè¯ãã®ã§ããã«ããã¼ã«èªä½ã®ãã¼ã¸ã§ã³ãè¨èªã®ãã¼ã¸ã§ã³ãã©ã¤ãã©ãªã®ãã¼ã¸ã§ã³ãå ¨ã¦ããã¸ã§ã¯ããã£ã¬ã¯ããªã«å±æåããã
- ãã¯ãæ©æ§ãæ¨æºã§åå¨ãã
- ããã¾ã使ããªããã©è±åºãããã«ã§ãã
ä¸æåã¾ã§ã¯ãªã¢ã·ãã°ããºã¿ãããªæ ã ã£ããã ãã©ãæè¿ã¯Closure Compilerã«ããã³ã³ãã¤ã«æé©åãè¡ãããããå°éæ§ãã§ãã¯ãè¡ããã¨ã§ãã³ãã«ãµã¤ãºãå°ãããªã£ãããTypeScriptã®åå®ç¾©ãã¡ã¤ã«ãèªã¿è¾¼ãã§ãã®ã¾ã¾ä½¿ããããã«ãã便å©ãªãã©ã°ã¤ã³ãç»å ´ãããã¨ãããªãæ´»çºã«éçºãè¡ããã¦ãããã¡ãªã¿ã«Scala.jsã¯ä»å¹´ã§10å¨å¹´éçºããã¦ããã
Scala.jsã§Hello, Worldãã
è½æ¸ãã¯ãã¦ãããå®éã«Scala.jsã§Hello, Worldãè¡ã£ã¦ã¿ãããæåã¯Node.jsãã©ã³ã¿ã¤ã ã¨ãã¦éã¶ãã¨ã«ããã
scala-cli
ã³ãã³ãã使ãã®ã§ã以ä¸ã®è¨äºãåèã«ãScalaã®éçºç°å¢ãç¨æãã¦ã»ããã
次ã«ã以ä¸ã®ãããªã³ã¼ããhellojs.scala
ã¨ãã¦ä¿åãã¦ã»ãã:
import scala.scalajs.js object Main { def main(args: Array[String]): Unit = { val msg = "Hello World from Scala.js" println(msg) } }
ãªãã®å¤å²ããªãHello worldã ã
scala-cli
ã«--js
ãã©ã¡ã¼ã¿ãã¤ãã¦å®è¡ãããã¨ã§ãJVMä¸ã§ã¯ãªãScala.jsãçµç±ãã¦JavaScriptã«å¤æããä¸ã§å®è¡ã§ãã:
% scala-cli --js scalajs.scala Compiling project (Scala 3.3.0, Scala.js) Compiled project (Scala 3.3.0, Scala.js) Hello World from Scala.js
ã¾ããscala-cli
ã®package
ãµãã³ãã³ããå©ç¨ãããã¨ã§ãnode.jsã§å®è¡å¯è½ãªjsãã¡ã¤ã«ãçæã§ãã:
% scala-cli --power package --js scalajs.scala -o hello.js % node hello.js Hello World from Scala.js
Scala CLIã¯ã¹ã¯ãªããã£ã³ã°/REPLç¨éã®ãã¼ã«ãªã®ã§ãæ¬æ ¼çãªéçºã®ããã«ã¯sbtãmillã¨ãã£ããã«ããã¼ã«ã使ããã¨ã«ãªãã
ãã©ã¦ã¶ã§åãjsãä½ã
次ã¯ããã©ã¦ã¶ã§Scala.jsãåä½ããã¦ã¿ãããScalaã®ãã«ããã¼ã«sbt
ã«ã¯ãã³ãã¬ã¼ãæ©è½ããããsbt new
ã¨å
¥åããã¨ããããã®ãã³ãã¬ã¼ããæ示ãã¦ããããããã§ã¯Viteã使ã£ãScala.jsã®ãã«ãç°å¢ãæ§ç¯ãããViteã¨tsc
ãããã§ããããã«ãViteç¨ãã©ã°ã¤ã³ããã«ããã¼ã«sbtã¨é£æºããScala.jsã®ãã©ã³ã¹ãã¤ã«çµæããªã³ã¯ãã¦ãããã®ã ã
% sbt new Welcome to sbt new! Here are some templates to get started: a) scala/toolkit.local - Scala Toolkit (beta) by Scala Center and VirtusLab b) typelevel/toolkit.local - Toolkit to start building Typelevel apps c) sbt/cross-platform.local - A cross-JVM/JS/Native project d) scala/scala3.g8 - Scala 3 seed template e) scala/scala-seed.g8 - Scala 2 seed template f) playframework/play-scala-seed.g8 - A Play project in Scala g) playframework/play-java-seed.g8 - A Play project in Java i) softwaremill/tapir.g8 - A tapir project using Netty m) scala-js/vite.g8 - A Scala.JS + Vite project n) holdenk/sparkProjectTemplate.g8 - A Scala Spark project o) spotify/scio.g8 - A Scio project p) disneystreaming/smithy4s.g8 - A Smithy4s project q) quit Select a template: m # scalajsããã¸ã§ã¯ããä½æãã name [scalajs-vite-example]: scalajs-vite # é©å½ãªååãæå®ãã use_yarn [TRUE/false]: # yarnã使ããªããã®ã¾ã¾Enterãæå®ãã % cd scalajs-vite # ä½ãããããã¸ã§ã¯ãã«ç§»åãã
ããã¸ã§ã¯ããä½ãçµãã£ãããé¢é£ã©ã¤ãã©ãªãã¤ã³ã¹ãã¼ã«ãã¦ãã¹ããµã¼ããèµ·åãã¦ã¿ãããã¾ãã¯yarn
ãå®è¡ããyarn run dev
ãå®è¡ãã¦ã¿ã:
% yarn ... % yarn run dev ... (ååã¯å°ãæéãããã) ... VITE v4.4.9 ready in 29747 ms â Local: http://localhost:5173/ â Network: use --host to expose â press h to show help
ãã¼ã«ã«ãµã¼ããç«ã¡ä¸ããã®ã§ããã®ã¢ãã¬ã¹ã«ã¢ã¯ã»ã¹ããã¨é©ããªãããScala.jsã§ãã©ã³ã¹ãã¤ã«ãããjsãåãã¦ãããèªåçã«ã½ã¼ã¹ã³ã¼ãã®å¤æ´ã«è¿½å¾ããã«ã¯ãããã«å ãã¦sbt '~fastLinkJS'
ãèµ·åãã¦ãããfastLinkJS
ã¯Scala.jsããã«ããã¦jsãã¡ã¤ã«ãçæããã³ãã³ãã ãããã¦sbtã§ã¯~
ãã³ãã³ãã®å
é ã«ä»ãããã¨ã§ãã¡ã¤ã«ã®å¤æ´ãæ¤ç¥ãã¦èªåçã«ã³ãã³ããå®è¡ãç´ãã¦ãããã
æçµçãªãã³ãã«ãã¡ã¤ã«ãçæããã«ã¯yarn run build
ãå®è¡ãã:
% yarn run build â 9 modules transformed. dist/index.html 0.45 kB â gzip: 0.30 kB dist/assets/index-1516cc57.css 0.20 kB â gzip: 0.16 kB dist/assets/index-f1bf866e.js 27.73 kB â gzip: 6.55 kB â built in 12.60s Done in 12.91s.
ããã¨dist/
以ä¸ã«å¿
è¦ãªãã¡ã¤ã«ãå
¨ã¦åºåããããScalaã®æ¨æºã©ã¤ãã©ãªãªã©ãã«ãã¼ããããã«å°ããã¡ã¤ã«ãµã¤ãºã大ãããªãããç¾ä»£çãªéä¿¡ç°å¢ã§ã¯ãã¾ãåé¡ã«ãªããªãã ããã
TypeScriptã®ã©ã¤ãã©ãªãå¼ã³åºã
Scala.jsããã¯JavaScriptãå¼ã³åºãæ©æ§ãå ã ããã®ã ããScalablyTypedã¨ããä»çµã¿(ãã©ã°ã¤ã³)ãå©ç¨ããã¨ãTypeScriptã®åå®ç¾©ãã¡ã¤ã«ãèªã¿è¾¼ãã§ãã®ã¾ã¾Scalaããå©ç¨ã§ããããã«ãã¦ãã¾ããç°¡åã«ç´¹ä»ãã¦ãããã
ScalablyTypedã¯ããã«ããã¼ã«ã®ãã©ã°ã¤ã³ã¨ãã¦åä½ããTypeScriptã®åå®ç¾©ãã¡ã¤ã«ãèªã¿è¾¼ãã§Scalaã®åå®ç¾©ã«å¤æããããã®éç¨ã¯ã³ã³ãã¤ã«ã¿ã¤ãã³ã°ã§ééçã«èªåçã«è¡ããããããçæããããã¡ã¤ã«ãªã©ãã³ãããããå¿ è¦ã¯ãªããIDEããã¯ãããªãTypeScriptã®ã©ã¤ãã©ãªã®åå空éãåºç¾ããããã«è¦ããã
ããã§ã¯å
¬å¼ãã¥ã¼ããªã¢ã«éããchart.js
ãScala.jsããå¼ã³åºãã¦ã¿ããã
ã¾ãã¯yarn
ã§ã©ã¤ãã©ãªã追å ãã¦ããã
% yarn add chart.js@2.9.4 % yarn add -D @types/chart.js@2.9.29 typescript@4.9.5
次ã«ScalablyTypedããã©ã°ã¤ã³ã¨ãã¦ç»é²ãããproject/plugins.sbt
ã«ä»¥ä¸ã®ããã«è¿½è¨ãã:
addSbtPlugin("org.scalablytyped.converter" % "sbt-converter" % "1.0.0-beta41")
æå¾ã«ãã«ãå®ç¾©ã§ãã®ãã©ã°ã¤ã³ã使ãããã«æ示ããããbuild.sbt
ã«ä»¥ä¸ã®3è¡ã追å ãã:
import org.scalajs.linker.interface.ModuleSplitStyle lazy val root = project .in(file(".")) .enablePlugins(ScalaJSPlugin) .enablePlugins(ScalablyTypedConverterExternalNpmPlugin) // è¿½è¨ .settings( name := "scalajs-vite", scalaVersion := "3.2.2", scalacOptions ++= Seq("-encoding", "utf-8", "-deprecation", "-feature"), scalaJSUseMainModuleInitializer := true, scalaJSLinkerConfig ~= { _.withModuleKind(ModuleKind.ESModule) .withModuleSplitStyle(ModuleSplitStyle.SmallModulesFor(List("example"))) }, libraryDependencies += "org.scala-js" %%% "scalajs-dom" % "2.4.0", externalNpm := baseDirectory.value, // è¿½è¨ useYarn := true, // è¿½è¨ )
ããã§ä¸åº¦sbt
ãèµ·åãã~fastLinkJS
ã³ãã³ããå®è¡ãããã¨ã§ãã¾ãåãã確èªãããååã¯åãã¤ã³ãã¼ããã¦Scalaã®åå®ç¾©ã«å¤æãã¦ããããããã°ããæéããããã
ãã¦ãchart.js
ã¯canvas
è¦ç´ ã«ãã£ã¼ããã¬ã³ãããã index.html
ãç·¨éãã¦ã¿ã°ãå¢ããã:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" type="image/svg+xml" href="favicon.svg" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vite App</title> </head> <body> <div id="app"></div> <canvas id="chart"></canvas><!-- 追å --> <script type="module" src="/main.js"></script> </body> </html>
次ã¯ããã«å®éã«ãã£ã¼ããã¬ã³ãããã³ã¼ããæ¸ãã¦ãããScalablyTypedã¯ãã¤ã³ãã¼ãããTypeScriptã®åå®ç¾©ãtypings.
以ä¸ã®ããã±ã¼ã¸ã«å±éãã*1ãããã使ã£ã¦src/main/scala/example/Main.scala
ã«ãã£ã¼ãä½æç¨ã®è¨å®ã追å ããã
val chartConfig = { // ã¢ã¸ã¥ã¼ã«ç´ä¸ã®ã·ã³ãã«ã¯mod.ã«å±éãããã // ä¾ãã° { ChartData } from 'chart'ã®ãããªã·ã³ãã«ãããã import typings.chartJs.mod.* new ChartConfiguration { // typeã¯Scalaã®äºç´èªãªã®ã§`type`ã«å±éããã `type` = ChartType.bar data = new ChartData { datasets = js.Array( new ChartDataSets { label = "Price" borderWidth = 1 backgroundColor = "green" }, new ChartDataSets { label = "Full price" borderWidth = 1 backgroundColor = "blue" } ) } options = new ChartOptions { scales = new ChartScales { yAxes = js.Array(new CommonAxe { ticks = new TickOptions { beginAtZero = true } }) } } } }
ããåé·ã ããæ£ãããã£ã¼ãã®å®ç¾©ãè¨å®ã§ããã
ããã«ãã£ã¼ããæç»ããããã«Main.scala
ãç·¨éãã:
@main def helloWorld(): Unit = { import typings.chartJs.mod.* import scala.scalajs.js.JSConverters.* val canvas: dom.HTMLCanvasElement = dom.document.querySelector("#chart").asInstanceOf val chart = Chart.apply.newInstance2(canvas, chartConfig) // ãã¼ã¿ã追å ãããtoJSArrayã§JavaScriptã®Arrayã«å¤æã§ãã chart.data.labels = Seq("foo", "bar", "buzz").toJSArray chart.data.datasets.get(0).data = Seq(10.0, 20.0, 30.0).toJSArray chart.data.datasets.get(1).data = Seq(10.0, 20.0, 30.0).toJSArray chart.update() }
ãããå®è¡ããã¨ãã©ã¦ã¶ã«ã¯chart.js
ã«ãããã£ã¼ãã表示ãããã
Scala.jsã¨UIã©ã¤ãã©ãª
Scala.jsã«ã¯Laminarã¨ããUIã©ã¤ãã©ãªãåå¨ãã¦ããããªã¢ã¯ãã£ããªãã¼ã¿ã¹ããªã¼ã ãçµç±ããUIãæ§ç¯ã§ãããè¦ããã«Reactã¿ãããªãã¨ã¯ã§ããããã ããLaminarã¯VDOMãå©ç¨ãããã¤ãã³ãã«ãã¨ã¥ãã¦ç´æ¥è¦ç´ ãç·¨éããã
Laminarã«ã¤ãã¦ã¯ä»¥ä¸è¨äºã§å°ã解説ãã¦ãã:
Laminarã§ã¯ã以ä¸ã®ããã«ç´æçã«ãã¼ã¿ã¨è¦ç´ ã¨ãç´ä»ããããå¤é¨ãã¼ã¿ã¨ã®é£æºãFuture
(JSã§è¨ãã¨ããã®Promise
)ãå©ç¨ãã¦è¡ããããã«ãªã£ã¦ããã
def counterButton(): Element = val counter = Var(0) // Intã®ç¶æ ãæ㤠button( tpe := "button", "count is ", child.text <-- counter, // ããã¹ãã¯counterã®å¤ã«ç´ä»ã // ã¯ãªãã¯æã¯counterãæ´æ°ãã onClick --> { event => counter.update(c => c + 1) }, ) end counterButton
Laminarãå©ç¨ããä¾ã¨ãã¦110416æ°ã®Laika-Laminarãããã
ã¾ã¨ã
ãã®è¨äºã§ã¯æè¿ã®Scala.jsäºæ ãç´¹ä»ãããããã¾ã§Scalaãæ¸ãããã¨ããã人ãæ¸ãããã¨ããªã人ããScala.jsã«ããå®å ¨ã§è¡¨ç¾åã®é«ãããã³ãã¨ã³ãéçºã«ãã£ã¬ã³ã¸ãã¦ã¿ã¦ã¯ãããã ããããSmithy4sãªã©ã®ãã¼ã«ã使ãã°ãããã³ãã¨ã³ãã¨ããã¯ã¨ã³ãã§å ±éã®ã¤ã³ã¿ã¼ãã§ã¤ã¹å®ç¾©ã使ã£ãããã§ããã
*1:è¨å®ã§å¤æ´å¯è½