Scala.Rx с ошибкой компиляции примера ScalaTags

Я попробовал пример scala.js https://github.com/lihaoyi/hands-on-scala-js и его scala.rx с частью scalatags в расширенном разделе. Примеры компиляции выполняются нормально, но когда я пытаюсь использовать последнюю версию scala.rx v 0.3.1, я получаю следующие ошибки компиляции:

[info] Compiling 19 Scala sources to /home/code/workspace/hands-on-scala-js-master/examples/demos/target/scala-2.11/classes...
[error] /home/code/workspace/hands-on-scala-js-master/examples/demos/src/main/scala/advanced/BasicRx.scala:14: 
[error] This Rx might leak! Either explicitly mark it unsafe (Rx.unsafe) or make an implicit RxCtx available
[error] in the enclosing scope, for example, by adding (implicit ctx: Ctx.Owner) to line 12: method main
[error]     val numChars = Rx{txt().length}
[error]                      ^
[error] /home/code/workspace/hands-on-scala-js-master/examples/demos/src/main/scala/advanced/BasicRx.scala:15: 
[error] This Rx might leak! Either explicitly mark it unsafe (Rx.unsafe) or make an implicit RxCtx available
[error] in the enclosing scope, for example, by adding (implicit ctx: Ctx.Owner) to line 12: method main
[error]     val numWords = Rx{
[error]                      ^
[error] /home/code/workspace/hands-on-scala-js-master/examples/demos/src/main/scala/advanced/BasicRx.scala:55: 
[error] This Rx might leak! Either explicitly mark it unsafe (Rx.unsafe) or make an implicit RxCtx available
[error] in the enclosing scope, for example, by adding (implicit ctx: Ctx.Owner) to line 42: method main2
[error]       for(fruit <- fruits) yield Rx {
[error]                                     ^
[error] /home/code/workspace/hands-on-scala-js-master/examples/demos/src/main/scala/advanced/BasicRx.scala:65: diverging implicit expansion for type Nothing => scalatags.JsDom.Frag
[error] starting with method rxFrag in object BasicRx
[error]         ul(fragments)
[error]            ^
[error] /home/code/workspace/hands-on-scala-js-master/examples/demos/src/main/scala/advanced/BasicRx.scala:72: not found: value Obs
[error]     Obs(r, skipInitial = true){
[error]     ^
[error] /home/code/workspace/hands-on-scala-js-master/examples/demos/src/main/scala/advanced/BasicRx.scala:72: not found: value skipInitial
[error]     Obs(r, skipInitial = true){
[error]            ^
[warn] /home/code/workspace/hands-on-scala-js-master/examples/demos/src/main/scala/webpage/WeatherSearch.scala:53: non-variable type argument scala.scalajs.js.Dynamic in type pattern scala.scalajs.js.Array[scala.scalajs.js.Dynamic] is unchecked since it is eliminated by erasure
[warn]         case jsonlist: js.Array[js.Dynamic] =>
[warn]                           ^
[warn] one warning found
[error] 6 errors found
[error] (demos/compile:compile) Compilation failed

Кажется, что концепция владения как-то изменилась, и также нет объекта-компаньона Obs.

Я пытался исправить эти ошибки в BasicRx.scala: Старый код:

@JSExport
def main(container: html.Div) = {

Новый код (исправление утечки):

@JSExport
def main(container: html.Div) = {
  implicit val ctx: Ctx.Owner = Ctx.Owner.safe() 

Старый код:

  implicit def rxFrag[T <% Frag](r: Rx[T]): Frag = {
    def rSafe: dom.Node = span(r()).render
    var last = rSafe

    Obs(r, skipInitial = true){
      val newLast = rSafe
      js.Dynamic.global.last = last
      last.parentNode.replaceChild(newLast, last)
      last = newLast
    }
    last
  }

Новый код (исправление конверсии):

  implicit def rxFrag[T <% Frag](r: Rx[T]): Frag = {
    def rSafe: dom.Node = span(r()).render
    var last = rSafe

    val thunk = () => {
      val newLast = rSafe
      js.Dynamic.global.last = last
      last.parentNode.replaceChild(newLast, last)
      last = newLast
    }
    new Obs(thunk, r)
    last
  }

Но все равно получите следующую ошибку:

[info] Compiling 19 Scala sources to /home/code/workspace/hands-on-scala-js-master/examples/demos/target/scala-2.11/classes...
[warn] /home/code/workspace/hands-on-scala-js-master/examples/demos/src/main/scala/webpage/WeatherSearch.scala:53: non-variable type argument   scala.scalajs.js.Dynamic in type pattern scala.scalajs.js.Array[scala.scalajs.js.Dynamic] is unchecked since it is eliminated by erasure
[warn]         case jsonlist: js.Array[js.Dynamic] =>
[warn]                           ^
[error] /home/code/workspace/hands-on-scala-js-master/examples/demos/src/main/scala/advanced/BasicRx.scala:74: No implicit Ctx.Data is available here!
[error]     def rSafe: dom.Node = span(r()).render
[error]                                 ^

Как это исправить? И правильно ли сделано исправление утечки?

Обновление скалатагов до 0.5.4. не имел никакого влияния.

1 ответ

Решение

Я помог внести вклад в 0.3.x ветку scala.rx - и да, API в значительной степени изменился с 0.2.x. Тем не менее, я также поддерживаю более свежую версию кода "фреймворка", который вы смотрите здесь:

https://github.com/Voltir/framework.rx/blob/master/src/main/scala/framework/Framework.scala

Кроме того, оказывается, что в случае использования js.App и его def main(), правильный способ получить Ctx.Owner это использовать import rx.Ctx.Owner.Unsafe._, До тех пор, пока эта основная функция оценивается конечное число раз (то есть один раз) за загрузку страницы, можно допустить "утечку". Ваше использование Ctx.Owner.safe() не будет работать, потому что компилятор не может доказать, что main вызывается только конечное число раз.

Один полный пример всего этого можно найти в демонстрационном проекте этой библиотеки: https://github.com/Voltir/route.rx

Другие вопросы по тегам