2016-03-02 60 views
3

我嘗試了scala.js示例https://github.com/lihaoyi/hands-on-scala-js及其帶有scalatags的scala.rx,它是高級部分的一部分。 示例編譯是運行正常,但是當我嘗試使用最新的scala.rx v 0.3.1我獲得以下編譯錯誤:Scala.Rx with ScalaTags示例編譯錯誤

[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 

似乎所有權概念已經以某種方式改變,也沒有觀測數據同伴對象。

我試着把這些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]        ^

如何解決這個問題呢? 並正確完成泄漏修復?

將scalatags更新爲0.5.4。沒有任何影響。

回答

4

我幫助了scala.rx的0.3.x分支 - 而且是的,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

+0

或者我究竟在做什麼,我有Ctx.Owner.unsafe上面提到的例子: 的https:/ /github.com/Voltir/form.rx-demo/blob/master/src/main/scala/example/ScalaJSExample.scala#L464 – Voltaire