[关闭]
@atry 2016-08-09T13:18:08.000000Z 字数 2643 阅读 3670

附录:Binding.scala快速上手指南

基本用法

Binding.scala 的基本用法很像 ReactJS ,也是通过编写模板把数据映射成 HTML 。

第零步:构建脚本配置

首先,你需要设置项目的构建脚本。Binding.scala 就是普通的 Scala.js 库,按普通的 Scala.js 项目配置方式即可。具体参考 Scala.js 的教程或者TodoMVC的源码仓库

第一步:添加 Binding.scala 的依赖

修改你的 build.sbt 文件,加入以下两行

  1. libraryDependencies += "com.thoughtworks.binding" %%% "dom" % "latest.release"
  2. addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)

第二步:定义 HTML 模板

  1. @dom
  2. def spinner(i: Var[Int]) = {
  3. <div>
  4. <button onclick={ event: Event => i := i.get - 1 }>-</button>
  5. { i.bind.toString }
  6. <button onclick={ event: Event => i := i.get + 1 }>+</button>
  7. </div>
  8. }
  9. @dom
  10. def render = {
  11. val i = Var(0)
  12. <div>
  13. { spinner(i).bind }
  14. 控件当前值是:{ i.bind.toString }
  15. </div>
  16. }

你可以在Binding.scala的DEMO网站实际运行一下试试。

Scala 代码的语法和 ECMAScript 6 很接近。有 JavaScript 经验的同学只要参考
From ES6 to Scala 就可以迁移到 Scala.js 了。

以上 Scala 代码创建了两个 HTML 模板,其中 spinner 是个数字选择组件,render 是页面的内容。Binding.scala 支持 Scala 代码和 HTML 模板混合编写,所以 onclick={...} 把一个 Scala 函数设置给了 HTML 属性 onclick

上述代码用到了 Binding.scala 的几个API:

注意:{ event: Event => i := i.get + 1 }没加 @dom ,是个普通的函数而不是绑定表达式,所以其中可以使用 get:=

这两个 HTML 模板之间传递了绑定变量 i 作为参数。所以,当 spinner 内的 onclick 修改 i 时,spinnerrender 中的 i.bind 都会触发,实现了类似双向绑定的效果。

第三步:渲染 HTML

编写完功能后,你需要在 main 中把 render 渲染出来。

  1. @JsExport def main() = {
  2. dom.render(document.body, render)
  3. }

最后在静态 HTML 中调用 main() 方法:

  1. <script type="text/javascript"> SampleMain().main() </script>

这样一来整个程序就写完了。

容器和循环

复杂的网页上往往会有重复的元素,可以把数据保存到 Vars 容器,然后用 for / yield 渲染。

比如

  1. @dom def render = {
  2. val logs = Vars("Hello", "Binding.scala")
  3. <div>
  4. { for { log <- logs } yield <div>{ log }</div> }
  5. </div>
  6. }

以上代码通过 for / yield 语句渲染了两行文字,你可以在Binding.scala的DEMO网站实际运行一下试试

Vars 是可以被监听的容器。所以,每当 Vars 的内容修改时,渲染出的网页也会自动修改:

  1. @dom def render = {
  2. val logs = Vars("Input code:")
  3. val input = <input type="text"/>
  4. val submitHandler = { event: Event =>
  5. logs.get += input.value
  6. logs.get += js.eval(input.value).toString
  7. input.value = ""
  8. event.preventDefault()
  9. }
  10. <form onsubmit={ submitHandler }>
  11. { for { log <- logs } yield <div>{ log }</div> }
  12. { input }
  13. </form>
  14. }

以上代码实现了一个代码控制台,你可以在输入框中输入代码,按下回车键,就能看到代码执行结果。
你可以在Binding.scala的DEMO网站实际运行一下试试。

Vars.get 类似 Var.get,用来容器的当前值,返回值是个 scala.collection.mutable.Buffer
所以你还可以对 Var.get 取得的当前值调用 Buffer+= 等各种方法,直接进行修改容器的当前值。
当你修改这个 Buffer 时,会触发 Binding.scala 自动执行对应操作,把修改集映射到 for / yield 生成的页面上。

比如,logs.get += input.value 添加了一个字符串,那么渲染出的网页上也会添加一行包含该字符串的 <div> ,而不需要修改网页上原有的其他部分。

注意,Vars.get+= 就像 Var.get:= 一样,也不能在@dom绑定表达式或代码模板中调用,而只能在其他函数中调用。
比如以上代码的 submitHandler 回调函数不是一个 @dom 函数,所以可以在其中修改 logs

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注