Created
October 7, 2016 11:19
-
-
Save vaclavsvejcar/05e3190ec91f3e02ba9031b765181475 to your computer and use it in GitHub Desktop.
Scalatags ↔ Scala.Rx integration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.scalajs.dom.html.Span | |
import org.scalajs.dom.{Element, Node} | |
import rx._ | |
import scala.annotation.tailrec | |
import scala.util.{Failure, Success} | |
import scalatags.JsDom.all._ | |
/** | |
* Provides support for using [[https://github.com/lihaoyi/scala.rx Scala.Rx]] together with the | |
* [[https://github.com/lihaoyi/scalatags Scalatags]] library. This version has been tested with | |
* ''Scala.Rx'' 0.3.0 and ''Scalatags'' 0.6.0. | |
* | |
* @author Vaclav Svejcar ([email protected]) | |
*/ | |
object rxinterop { | |
/** | |
* Sticks some Rx into a Scalatags fragment, which means hooking up an Obs | |
* to propagate changes into the DOM. | |
*/ | |
implicit def RxFrag[T](rxValue: Rx[T])(implicit f: T => Frag, ctx: Ctx.Owner): Frag = { | |
@tailrec def clearChildren(node: org.scalajs.dom.Node): Unit = { | |
if (node.firstChild != null) { | |
node.removeChild(node.firstChild) | |
clearChildren(node) | |
} | |
} | |
def fSafe: Frag = rxValue match { | |
case r: Rx.Dynamic[T] => r.toTry match { | |
case Success(v) => v.render | |
case Failure(e) => span(e.getMessage, backgroundColor := "red").render | |
} | |
case v: Var[T] => v.now.render | |
} | |
var last: Node = fSafe.render | |
val container: Span = span(cls := "_rx")(last).render | |
rxValue.triggerLater { | |
val newLast = fSafe.render | |
//Rx[Seq[T]] can generate multiple children per propagate, so use clearChildren instead of replaceChild | |
clearChildren(container) | |
container.appendChild(newLast) | |
last = newLast | |
} | |
bindNode(container) | |
} | |
implicit def RxAttrValue[T: AttrValue](implicit ctx: Ctx.Owner) = new AttrValue[Rx.Dynamic[T]] { | |
def apply(t: Element, a: Attr, r: Rx.Dynamic[T]): Unit = { | |
r.trigger { | |
implicitly[AttrValue[T]].apply(t, a, r.now) | |
} | |
} | |
} | |
implicit def RxStyleValue[T: StyleValue](implicit ctx: Ctx.Owner) = new StyleValue[Rx.Dynamic[T]] { | |
def apply(t: Element, s: Style, r: Rx.Dynamic[T]): Unit = { | |
r.trigger { | |
implicitly[StyleValue[T]].apply(t, s, r.now) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment