# 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://github.com/search?l=Scala&o=desc&q="com.thoughtworks.binding"&s=indexed&type=Code&utf8=✓)
[](http://todomvc.com/examples/binding-scala/)
[](https://gitter.im/ThoughtWorksInc/Binding.scala?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://stackoverflow.com/questions/tagged/binding.scala?sort=votes)
[](https://travis-ci.org/ThoughtWorksInc/Binding.scala)
[](https://javadoc.io/page/com.thoughtworks.binding/binding_2.12/latest/com/thoughtworks/binding/index.html)
[](https://index.scala-lang.org/thoughtworksinc/binding.scala)
**Binding.scala** is a data-binding library for [Scala](http://www.scala-lang.org/), running on both JVM and [Scala.js](http://www.scala-js.org/).
Binding.scala can be used as the basis of UI frameworks, however latest Binding.scala 12.x does not contain any build-in UI frameworks any more. For creating reactive HTML UI, you may want to check out [html.scala](https://github.com/GlasslabGames/html.scala), which is an UI framework based on Binding.scala, and it is also the successor of previously built-in [dom](https://javadoc.io/page/com.thoughtworks.binding/dom_sjs0.6_2.12/latest/com/thoughtworks/binding/dom.html) library.
See [Binding.scala • TodoMVC](http://todomvc.com/examples/binding-scala/) or [ScalaFiddle DEMOs](https://github.com/ThoughtWorksInc/Binding.scala/wiki/ScalaFiddle-DEMOs) as examples for common tasks when working with Binding.scala.
## Comparison to other reactive web frameworks
Binding.scala and html.scala has more features and less concepts than other reactive web frameworks like [ReactJS](https://facebook.github.io/react/).
Binding.scala
ReactJS
Support HTML literal?
Yes
Partially supported. Regular HTML does not compile, unless developers manually replaces class and for attributes to className and htmlFor, and manually converts inline styles from CSS syntax to JSON syntax.
Algorithm to update DOM
Precise data-binding, which is faster than virtual DOM
Virtual DOM differentiation, which requires manually managed key attributes for complicated DOM.
Lifecycle management for data-binding expressions
Automatically
N/A
Statically type checking
Yes, even for HTML tags and attribues
No
Learning curve
Always easy
Easy to start. Requires much more efforts to understand its corner cases.
See [Design](#design) section for more information.
## Getting started
We will build an Binding.scala web page during the following steps.
### Step 0: Setup a Sbt Scala.js project
See http://www.scala-js.org/tutorial/basic/ for information about how to setup such a project.
### Step 1: Add html.scala dependencies into your `build.sbt`:
``` scala
// Enable macro annotations by setting scalac flags for Scala 2.13
scalacOptions ++= {
import Ordering.Implicits._
if (VersionNumber(scalaVersion.value).numbers >= Seq(2L, 13L)) {
Seq("-Ymacro-annotations")
} else {
Nil
}
}
// Enable macro annotations by adding compiler plugins for Scala 2.12
libraryDependencies ++= {
import Ordering.Implicits._
if (VersionNumber(scalaVersion.value).numbers >= Seq(2L, 13L)) {
Nil
} else {
Seq(compilerPlugin("org.scalamacros" % "paradise" % "2.1.1" cross CrossVersion.full))
}
}
libraryDependencies += "org.lrng.binding" %%% "html" % "latest.release"
```
### Step 2: Create a `data` field, which contains some `Var` and `Vars` as data source for your data-binding expressions
``` scala
case class Contact(name: Var[String], email: Var[String])
val data = Vars.empty[Contact]
```
A `Var` represents a bindable variable,
which also implements `Binding` trait,
hence a `Var` can be seen as a binding expression as well.
If another expression depends on a `Var`, the value of the expression changes whenever value of the `Var` changes.
A `Vars` represents a sequence of bindable variables,
which also implements `BindingSeq` trait,
hence a `Vars` can be seen as a binding expression of a sequence as well.
If another comprehension expression depends on a `Vars`,
the value of the expression changes whenever value of the `Vars` changes.
### Step 3: Create a `@html` method that contains data-binding expressions
``` scala
@html
def table: Binding[Table] = {
Name
E-mail
{
for (contact <- data) yield {
{contact.name.bind}
{contact.email.bind}
}
}
}
```
A `@html` method represents an reactive XHTML template, which supports HTML literal.
Unlike normal XML literal in a normal Scala method,
the types of HTML literal are specific subtypes of `org.scalajs.dom.raw.Node` or `com.thoughtworks.binding.BindingSeq[org.scalajs.dom.raw.Node]`,
instead of `scala.xml.Node` or `scala.xml.NodeSeq`.
So we could have `@html def node: Binding[org.scalajs.dom.raw.HTMLBRElement] = `
and `@html def node: Binding[BindingSeq[org.scalajs.dom.raw.HTMLBRElement]] =
`.
A `@html` method is composed with other data-binding expressions in two ways:
1. You could use `bind` method in a `@html` method to get value of another `Binding`.
2. You could use `for` / `yield` expression in a `@html` method to map a `BindingSeq` to another.
You can nest `Node` or `BindingSeq[Node]` in other HTML element literals via `{ ... }` interpolation syntax.
### Step 4: Render the data-binding expressions to DOM in the `main` method
``` scala
@JSExport
def main(): Unit = {
html.render(document.body, table)
}
```
### Step 5: Invoke the `main` method in a HTML page
``` html
```
Now you will see a table that just contains a header, because `data` is empty at the moment.
### Step 6: Add some `