1

我想构建一个包含audio元素的小组件,它能够在间隔上循环。区间的两端将被定义为组件的属性。由于timeUpdate事件没有必要的精度(我希望至少保证 33Hz),我决定使用带有 的后端TimerSupport,并在currentTime它通过间隔结束时将其设置为起点。

val AudioRef = Ref[Audio]("audio")
class PlayerBackend extends TimerSupport
val AudioPlayer = ReactComponentB[String]("AudioPlayer")
  .initialState(0L)
    .backend(i => new PlayerBackend())
  .render_P(url => {
    <.audio(
       ^.ref := AudioRef,
      ^.autoPlay  := true,
      ^.controls  := true,
      <.source(^.src := "http://www.stephaniequinn.com/Music/Allegro%20from%20Duet%20in%20C%20Major.mp3"),
      "Your browser does not support the audio element."
    )
  })
  .componentDidMount({ c =>
    c.backend.setInterval(Callback.log({
      if (AudioRef(c).isDefined) ({
        AudioRef(c).get.currentTime
      }) else "nothing"
    }), 1000 millisecond)
  }).configure(TimerSupport.install)
  .build

这个小例子我只想打印播放器的当前位置,但由于某种原因(回调在组件安装时关闭后端上下文的副本?)AudioRef(c)指向音频元素的旧版本. 知道如何解决这个问题吗?我也对其他设计感兴趣,因为我对 ScalaJS 和 React 都没有真正的经验。

4

2 回答 2

1

问题在于log仅对其参数进行一次评估的调用,从而产生一个值,然后一遍又一遍地记录。正确的代码是这样的:

.componentDidMount({ c =>
  c.backend.setInterval(CallbackTo[Double] {
    if (AudioRef(c).isDefined) ({
      AudioRef(c).get.currentTime
    }) else 0
  } >>= Callback.log, 1000 millisecond)
})

它创建一个提取currentTime值(或什么都不提取)的回调,然后将 flatMaps 映射到另一个记录该值的回调。

于 2016-06-29T19:07:53.660 回答
0

我最终通过在 a 中currentTime获取音频元素来设置属性,所以我的解决方案目前看起来像这样:idCallback

class PlayerBackend($: BackendScope[String, Unit]) extends TimerSupport
val AudioPlayer = ReactComponentB[String]("AudioPlayer")
  .initialState(())
    .backend(i => new PlayerBackend(i))
  .render_P(url => {
    <.audio(
      ^.id := "audio",
      ^.autoPlay  := true,
      ^.controls  := true,
      <.source(^.src := "http://www.stephaniequinn.com/Music/Allegro%20from%20Duet%20in%20C%20Major.mp3"),
      "Your browser does not support the audio element."
    )
  })
  .componentDidMount({ c =>
    c.backend.setInterval(
      Callback({document.getElementById("audio").asInstanceOf[Audio].currentTime = 5.0}) ,
      1 seconds
    )
})
.configure(TimerSupport.install)
.build
于 2016-06-29T18:15:57.670 回答