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、パラメーターを 1 回だけ評価する呼び出しにあり、結果として単一の値が生成され、それが何度も何度もログに記録されます。正しいコードは次のようになります。

.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 に答える