# Binding.scala
**Repository Path**: thoughtworks/Binding.scala
## Basic Information
- **Project Name**: Binding.scala
- **Description**: Binding.scala 是一个用 Scala 语言编写的数据绑定框架,可以在 JVM 和 Scala.js 上运行。它可以用作 reactive web freamework。 它允许你使用原生 XHTML 语法去创建 reactive DOM 节点,这种 DOM 节点可以在数据源发生变化时自动地改变。
- **Primary Language**: Scala
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2021-06-03
- **Last Updated**: 2022-04-08
## Categories & Tags
**Categories**: utils
**Tags**: None
## README
# Binding.scala
[](https://gitter.im/ThoughtWorksInc/Binding.scala?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://travis-ci.org/ThoughtWorksInc/Binding.scala)
[](https://maven-badges.herokuapp.com/maven-central/com.thoughtworks.binding/binding_2.11)
[](https://maven-badges.herokuapp.com/maven-central/com.thoughtworks.binding/dom_sjs0.6_2.11)
[](https://maven-badges.herokuapp.com/maven-central/com.thoughtworks.binding/futurebinding_2.11)
[](https://maven-badges.herokuapp.com/maven-central/com.thoughtworks.binding/jspromisebinding_sjs0.6_2.11)
**Binding.scala** 是一个用 [Scala](http://www.scala-lang.org/) 语言编写的数据绑定框架,可以在 JVM 和 [Scala.js](http://www.scala-js.org/) 上运行。
Binding.scala 可以用作 **[reactive](https://en.wikipedia.org/wiki/Reactive_programming) web freamework**。
它允许你使用原生 XHTML 语法去创建 reactive DOM 节点,这种 DOM 节点可以在数据源发生变化时自动地改变。
使用 Binding.scala 时可以参考 [Binding.scala • TodoMVC](http://todomvc.com/examples/binding-scala/) 或者[其他 DEMOs](https://thoughtworksinc.github.io/Binding.scala/),他们中包含了许多常见功能的实现。
## 与其他 reactive web framework 对比
与其他 reactive web framework(例如 [ReactJS](https://facebook.github.io/react/))对比,Binding.scala 有更多的特性以及更少的概念。
|
Binding.scala |
ReactJS |
HTML 语法支持 |
支持 |
部分支持。Regular HTML 不会编译,除非开发者人为地将 class 属性和 for 属性改为 className 和 htmlFor ,并且人为地将 行内样式 的语法从 CSS 语法改为 JSON 语法。 |
DOM 更新算法 |
精准的数据绑定,比虚拟 DOM 更快 |
虚拟 DOM 之间存在差异,对于复杂的 DOM 你需要手动地管理 key 属性。 |
数据绑定表达式的生命周期管理 |
完全自动 |
无 |
静态类型检查 |
支持,甚至是 HTML 标签和属性 |
不支持 |
学习曲线 |
一直很简单 |
容易上手,但在理解边界情况时需要投入大量精力。 |
更多详细信息,请查看[设计](#设计)。
## 开始使用
我们将在接下来的步骤里编写一个 Binding.scala 网页。
### 第 0 步:配置一个 Sbt Scala.js 项目
参考 http://www.scala-js.org/tutorial/basic/ 获取详细信息。
### 第 1 步:在你的 `build.sbt` 中添加 Binding.scala 依赖项
``` scala
libraryDependencies += "com.thoughtworks.binding" %%% "dom" % "latest.release"
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
```
### 第 2 步:创建一个 `data` 域,其中包含一些 `Var` 和 `Vars` 作为你数据绑定表达式的数据源
``` scala
case class Contact(name: Var[String], email: Var[String])
val data = Vars.empty[Contact]
```
一个 `Var` 代表一个可绑定变量,
同时它也实现了 `Binding` 特性,
这就意味着一个 `Var` 也可以被视为一个是数据绑定表达式。
如果其他数据绑定表达式依赖与一个 `Var` ,那么该表达式的值将在这个 `Var` 的值改变时作出相应的改变。
一个 `Vars` 代表一个可绑定变量序列,
同时它也实现了 `BindingSeq` 特性,
这就意味着一个 `Vars` 也可以被视为一个序列的数据绑定表达式。
如果另一个数据绑定表达式依赖与一个 `Vars` ,
那么该表达式的值将在这个 `Vars` 的值改变时作出相应的改变。
### 第 3 步:创建一个含有数据绑定表达式的 `@dom` 方法
``` scala
@dom
def table: Binding[Table] = {
Name |
E-mail |
{
for (contact <- data) yield {
{contact.name.bind}
|
{contact.email.bind}
|
}
}
}
```
一个 `@dom` 方法代表一个数据绑定表达式。
其返回值类型永远被包装成 `com.thoughtworks.binding.Binding` 特性。
例如, `@dom def x: Binding[Int] = 1`, `@dom def message: Binding[String] = "content"`
`@dom` 方法支持 HTML 语法。
并不像通常 Scala 方法中的 XML 语法,
HTML 语法的类型是 `org.scalajs.dom.raw.Node` 或者 `com.thoughtworks.binding.BindingSeq[org.scalajs.dom.raw.Node]` 的子类型,
而不是 `scala.xml.Node` 或者 `scala.xml.NodeSeq`。
因此我们写出这样的代码,`@dom def node: Binding[org.scalajs.dom.raw.HTMLBRElement] =
`
以及 `@dom def node: Binding[BindingSeq[org.scalajs.dom.raw.HTMLBRElement]] =
`。
由其他数据绑定表达式组成的 `@dom` 方法有两种编写方式:
1. 你可以在 `@dom` 方法中使用 `bind` 方法来获取其他 `Binding` 的值。
2. 你可以在 `@dom` 方法中使用 `for` 或者 `yield` 表达式将 `BindingSeq` 映射到其他的表达式上。
你可以通过使用 `{ ... }` 插入语法来在其他 HTML 元素中嵌入 `Node` 或者 `BindingSeq[Node]`。
### 第 4 步:在 `main` 方法中将数据绑定表达式渲染至 DOM
``` scala
@JSExport
def main(): Unit = {
dom.render(document.body, table)
}
```
### 第 5 步: 在 HTML 页面中调用 `main` 方法
``` html
```
至此,你会看见一个只含有表头的空表格,这是因为 `data` 现在是空的。
### 第 6 步:添加一些 `