为什么JavaFX中的绑定会以这种方式工作?

为什么JavaFX中的绑定会以这种方式工作?,java,javafx,data-binding,kotlin,Java,Javafx,Data Binding,Kotlin,我试图理解为什么数据绑定会以JavaFX中的方式工作。它允许您将observeValues绑定到其他observeValues,如下所示: val prop0 = SimpleStringProperty("xul") val prop1 = SimpleStringProperty("baz") prop0.bind(prop1) 执行此操作时,两个属性都将具有值baz 我还可以链接绑定: val prop0 = SimpleStringProperty("xul") val prop1 =

我试图理解为什么数据绑定会以JavaFX中的方式工作。它允许您将
observeValue
s绑定到其他
observeValue
s,如下所示:

val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
prop0.bind(prop1)
执行此操作时,两个属性都将具有值
baz

我还可以链接绑定:

val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
val prop2 = SimpleStringProperty("qux")

prop0.bind(prop1)
prop1.bind(prop2)
// all will have the value "qux"
val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
val prop2 = SimpleStringProperty("wom")

prop0.bindBidirectional(prop1)
prop1.bindBidirectional(prop2)
prop2.bindBidirectional(prop0)
文档中说我无法设置绑定属性的值:

prop0.value = "foo" // exception
虽然我可以使用循环绑定:

val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
val prop2 = SimpleStringProperty("qux")

prop0.bind(prop1)
prop1.bind(prop2)
// all will have the value "qux"
val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
val prop2 = SimpleStringProperty("wom")

prop0.bindBidirectional(prop1)
prop1.bindBidirectional(prop2)
prop2.bindBidirectional(prop0)
但简单的双向绑定将导致
堆栈溢出错误

prop0.bindBidirectional(prop1)
prop1.bindBidirectional(prop0)
这就是为什么(我想)有一种明确的双向绑定方式:

我不明白的是,为什么JavaFX将一个值单向绑定到多个其他值:

val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
val prop2 = SimpleStringProperty("qux")

prop0.bind(prop1)
// this will unbind prop0 from prop1
prop0.bind(prop2)
但是让我创建任意数量的
BidirectionalBinding
s?当双向绑定应该是两个单向绑定时,为什么这些概念之间存在差异

另一个奇怪的是,
Binding
接口创建了一个新实体,该实体将依赖于源
observeValue
s:

val num1 = SimpleIntegerProperty(1)
val num2 = SimpleIntegerProperty(2)
// creates a new binding, which will change its value
// whenever num1 or num2 changes
val sum = num1.add(num2)
可以是
dispose
d:

sum.dispose()
但是,当我调用
bind
bindBioderial
时,它不会返回一个一次性的
Binding


我读了文件,但没有解释这些事情。我错过什么了吗?什么是使这种行为成为必要的内部逻辑?

绑定属性
A
b
意味着只要绑定“就位”,
A
的值始终与
b
的值相同。除了
b
之外,将
a
绑定到
c
需要
a
的值与
b
c
相同,但它们可以包含不同的值。因此,只允许一个绑定。解除绑定属性会自动处理“处置”

双向绑定导致两个属性的值保持相同。更改一个会更新另一个,因此可以在任意数量的属性中绑定属性。如果更改属性,则双向绑定到该属性的所有其他属性都将更新,并且更改其他属性之一将更新属性本身,这也会更新所有其他属性。这里没问题。
JavaFX选择以不同的方式解除双向绑定:

a.bindBidirectional(b);
...
a.unbindBidirectional(b);
这需要处理“处理”


与属性之间的绑定相比,绑定对象是依赖于某些可观察的对象的
observeValue
对象。绑定对象自动向其依赖项注册
invalizationlistener
s,但是依赖项无法知道此侦听器可以删除,因为绑定对象不再使用。这就是为什么绑定对象允许您在不再需要它时通过调用它的
dispose
方法进行“清理”。

那么
StackOverflowerError
是一个bug吗?我应该报告吗?我想我在某个地方读到过,你不应该做循环双向绑定,但可能那不是官方来源,所以我不确定。你使用的是什么版本的JavaFX?在JavaFX11中,我没有得到
StackOverflowerError