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