【问题标题】:Type mismatch with Binding.scala involving scala.xml.Elem与涉及 scala.xml.Elem 的 Binding.scala 的类型不匹配
【发布时间】:2019-08-02 20:54:49
【问题描述】:

我未能编译一个简单的 Binding.scala 示例,而且作为一个新手,我不知道如何解决它。也许自述文件有点过时了? https://github.com/ThoughtWorksInc/Binding.scala-sample 的示例甚至更早,并导致弃用警告。

我的代码,基本上是从 README 中拼凑起来的,甚至简化了一点:

import com.thoughtworks.binding.dom
import org.scalajs.dom.document
import scala.scalajs.js.annotation.JSExport

@JSExport
object SampleMain {

  @dom
  def table = {
    <table border="1" cellPadding="5">
      <thead>
        <tr>
          <th>Name</th>
          <th>E-mail</th>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>
  }

  @JSExport
  def main(): Unit = {
    dom.render(document.body, table)
  }

}

fastOptJS 导致编译错误:

SampleMain.scala:25:9: overloaded method value render with alternatives:
[error]   (parent: org.scalajs.dom.raw.Node,children: com.thoughtworks.binding.Binding[com.thoughtworks.binding.Binding.BindingSeq[org.scalajs.dom.raw.Node]],dummy: Unit)Unit <and>
[error]   (parent: org.scalajs.dom.raw.Node,children: com.thoughtworks.binding.Binding.BindingSeq[org.scalajs.dom.raw.Node])Unit <and>
[error]   (parent: org.scalajs.dom.raw.Node,child: com.thoughtworks.binding.Binding[org.scalajs.dom.raw.Node])Unit
[error]  cannot be applied to (org.scalajs.dom.raw.HTMLElement, scala.xml.Elem)
[error]     dom.render(document.body, table)
[error]         ^

我怀疑类型推断有问题,并尝试了这种类型注释:def table: com.thoughtworks.binding.Binding[org.scalajs.dom.html.Table] 但这导致了另一个错误:

SampleMain.scala:11:6: type mismatch;
[error]  found   : scala.xml.Elem
[error]  required: com.thoughtworks.binding.Binding[org.scalajs.dom.html.Table]
[error]     (which expands to)  com.thoughtworks.binding.Binding[org.scalajs.dom.raw.HTMLTableElement]
[error]     <table border="1" cellPadding="5">
[error]      ^

我希望能解释一下这里出了什么问题。


解决方案:https://stackoverflow.com/a/55137909/1862339

【问题讨论】:

    标签: sbt scala.js binding.scala


    【解决方案1】:

    原来的问题是paradise 编译器插件在我的情况下没有被选中。我仅在子项目中使用 Binding.scala 构建 SBT 多项目,addCompilerPlugin 不会传播到子项目。要使其正常工作,需要将其添加到子项目的设置中,如下所示:

    lazy val client = (project in file("client"))
      .settings(
        libraryDependencies ++= Seq(
          "com.thoughtworks.binding" %%% "dom" % "11.6.0"
        ),
        addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
      )
      .enablePlugins(ScalaJSPlugin)
    

    之前我在build.sbt 的顶层有addCompilerPlugin,它不起作用并导致编译错误。

    【讨论】:

      【解决方案2】:

      应该有一条错误消息,要求您启用paradise 编译器插件。不幸的是,因为您使用的是 Scala 2.10,a bug in macro-compat 阻止您看到错误消息。

      所以长答案是:

      1. 通过在 build.sbt 中设置类似 scalaVersion in ThisBuild := "2.12.8" 的内容,将 Scala 升级到 2.11 或 2.12。
      2. 您将看到一条错误消息,要求您添加paradise 插件。
      3. 最后,根据报错信息在你的build.sbt中添加如下设置:
      addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
      

      【讨论】:

      • 实际上我使用的是 Scala 2.12,但没有看到有用的错误消息。也许是因为我使用的是 SBT 多项目构建?无论如何,编译器插件是我需要的提示,我修复了 SBT 中的错误配置(请参阅我的答案)。谢谢!
      【解决方案3】:

      检查您是否已将此添加到您的build.sbt

      addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)
      

      Binding.scala 的主宏(将 Scala XML 文字转换为特殊的 Binding 类型)在没有此插件的情况下无法工作,编译器只能看到原始类型 (scala.xml.Elem)。

      README 的Step 1 中提到了这一点。

      【讨论】:

      • 感谢您将我推向正确的方向!我的构建有点复杂,我确实(尝试)配置了编译器插件,但它不正确(请参阅我自己的答案)。您的洞察力确实帮助我理解了这个问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      • 2018-06-08
      相关资源
      最近更新 更多