-
Notifications
You must be signed in to change notification settings - Fork 108
The code that causes this error is that your bind
expression must not be outside of the scope of the @dom
macro. This can happen when creating a closure (for example someCollection.map { item <div>{item.bind}</div> }
) and can be resolved by:
-
Refactoring the code into its own
@dom
annotated method. -
Wrapping the code in a
Binding { }
block, for example:someCollection.map(item => Binding { renderItem(item.bind) } )
-
Converting
someCollection
to aBindingSeq
, for example:Constants(someCollection: _*).map { item => <div>{item.bind}</div> }
-
Provide a
scalaz.Traverse
type class for the collection (Run this example on ScalaFiddle)@dom def renderList(data: List[Binding[String]]) = <ol>{ import scalaz.std.list._ // Type classes for List for (b <- data) yield { <li>{b.bind}</li> } }</ol>
Wrap an HTML comment:
@dom def maybeEmpty: Binding[Node] = {
if (math.random > 0.5) {
<div>non-empty content</div>
} else {
<!-- empty content -->
}
}
Maybe you defined the <input ...>
and .bind
in the same @dom
method and the <input ...>
is after .bind
. Try to refactor the .bind
and <input ...>
into separate @dom
methods or let the .bind
expression nested in another DOM.
For example:
@dom def render(data: Binding[Int]) = {
val className: String = s"class-name-for-div-${data.bind}"
// <div> and <input> will be recreated once data changes.
<div class={className}>
<input type="text"/>
</div>
}
@dom def render(data: Binding[Int]) = {
val myInput = <input type="text"/>
val className: String = s"class-name-for-div-${data.bind}"
// <div> will be recreated once data changes.
// <input> will not be recreated.
<div class={className}>
{myInput}
</div>
}
@dom def render(data: Binding[Int]) = {
// <div> and <input> will not be recreated when data changes.
// Only the class attribute will be changed.
<div class={s"class-name-for-div-${data.bind}"}>
<input type="text"/>
</div>
}
@dom def render(data: Binding[Int]) = {
@dom val className: Binding[String] = s"class-name-for-div-${data.bind}"
// <div> and <input> will not be recreated when dataValue changes,
// only the class attribute will be changed.
<div class={className.bind}>
<input type="text"/>
</div>
}
For complex web views, stack size is not enough. You need to increase it for the compiler. For sbt you can do it adding a .sbtopts
in the root of your project with the line:
-J-Xss5m
Intellij doesn't support macro annotation. To make it happy, bring the following implicit into the scope
implicit def makeIntellijHappy(x: scala.xml.Node): Binding[org.scalajs.dom.raw.Node] = ???
This code is never actually executed.