如何在引用对象中创建代表 属性 的 Bacon.Property?

How can I create a Bacon.Property representing a property in a referenced object?

我开始玩 Bacon.js,但遇到了一个问题,我找不到任何示例。

我有一组节点,可能会引用其他节点。

在命令式代码中看起来像这样:

alice = { name: "Alice" }
bob   = { name: "Bob" }
carol = { name: "Carol" }

alice.likes = bob
bob.likes = carol
alice.likes.name //=> "Bob"

bob.name = "Bobby"
alice.likes.name //=> "Bobby"

alice.likes = carol
alice.likes.name //=> "Carol"

现在,我想为 alice.likes.name 设置一个 属性,必须更改 每当 alice.likes 指向不同的对象时,或者 name 属性 alice.likes 中的当前对象发生变化。

我想出了下面的代码(LiveScript 语法),它正确记录了 3 条消息:Bob、Bobby、Carol。

我正在使用 Bus 进行测试。

mkBus = (initialValue) ->
  bus = new Bacon.Bus()
  property = bus.toProperty(initialValue)
  property.push = (newValue) -> bus.push(newValue)
  property

alice = { pName: mkBus("Alice"), pLikes: mkBus(null) }
bob   = { pName: mkBus("Bob"),   pLikes: mkBus(null) }
carol = { pName: mkBus("Carol"), pLikes: mkBus(null) }

alice.pLikes.onValue (person) ->
  if person
    person.pName.onValue (vName) ->
      console.log vName

alice.pLikes.push(bob)
bob.pLikes.push(carol)

# Change name
bob.pName.push("Bobby")

# Change reference
alice.pLikes.push(carol)

问题:如何制作一个代表alice.likes.name名字的属性?

即:

nameOfAlicesFavourite.onValue (vName) ->
  console.log vName

我是 FRP 的新手,如果我做错了什么,请告诉我。

感谢@Bergi 将我指向 flatMap

flatMap 为源中的每个事件创建一个新流。我使用了 flatMapLatest,因此只有 最新 喜欢的人的名字更改才会在输出流上传输。

代码如下:

nameOfAlicesFavourite = alice.pLikes.flatMapLatest (person) ->
  if person
    person.pName
  else
    Bacon.never!