Skip to content
杨博 (Yang Bo) edited this page Nov 28, 2016 · 46 revisions

I get the error each instructions must be inside a SDE block, how can I fix this?

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(<div>_.bind</div>)) and can be resolved by:

  • Factoring the code into its own @dom annotated method.

  • Wrapping the code in a Binding { } block, for example:

    someCollection.map(item => Binding { <div>item.bind</div> } )
  • Converting someCollection to a BindingSeq, for example:

    Constants(someCollection: _*).map(<div>_.bind</div>)
  • Provide a scalaz.Traverse type class for the collection

    import scalaz.std.list._
    @dom renderList(data: List[String]) = <ol>{
      for (s <- data) yield {
        <li>{s}</li>
      }
    }</ol>

How do I create a Binding of HTML node with empty HTML content?

Wrap an HTML comment: Binding { <!-- Render nothing because ... --> }.

My input html forms misses focus/empties when a Var changes

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>
}

I am getting Stack Overflow when compiling.

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
Clone this wiki locally