Virtual DOM Middleware
Scala.js DOM backend and virtual-DOM-like rendering
As a virtual DOM
Avocet can be used as virtual-DOM-like middleware. Unlike other popular virtual DOM solutions, Avocet doesn't allocate additional memory for construction of a new virtual DOM copy. Also it does not allocate memory in changes inferring phase. Avocet's memory usage is constant.
// build.sbt
libraryDependencies += "com.natural-transformation" %%% "avocet-dom" % "1.0.0"
// In your code
import org.scalajs.dom._
import avocet.dom.render
import avocet.dom.event
import avocet.dsl._
import html._
case class Todo(id: String, text: String, done: Boolean)
def onSubmitClick() = {
val input = document
.getElementById("todo-input")
.asInstanceOf[html.Input]
val inputText = input.value
// Reset input
input.value = ""
val newTodo = Todo(
id = Random.alphanumeric.take(5).mkString,
text = inputText,
done = false
)
renderTodos(todos :+ newTodo)
}
def onTodoClick(todo: Todo) = {
renderTodos(
todos.updated(
todos.indexOf(todo),
todo.copy(done = !todo.done)
)
)
}
def renderTodos(todos: Seq[Todo]): Unit = render(document.body) {
optimize {
body(
div(clazz := "title", "Todos"),
ul(clazz := "list",
todos map { todo =>
li(
todo match {
case Todo(_, text, true) => strike(text)
case Todo(_, text, false) => span(text)
},
event("click")(onTodoClick(todo))
)
}
),
input(id := "todo-input", placeholder := "New ToDo"),
button("Submit", event("click")(onSubmitClick()))
)
}
}
val todos = Seq(
Todo("1", "Start use Avocet", done = false),
Todo("2", "Lean back and have rest", done = false)
)
renderTodos(todos)