【问题标题】:Why do bindings in JavaFX work in the way they do?为什么 JavaFX 中的绑定以它们的方式工作?
【发布时间】:2019-04-05 17:01:30
【问题描述】:

我试图理解为什么数据绑定的工作方式与它在 JavaFX 中的工作方式相同。它可以让您将ObservableValues 绑定到其他ObservableValues,如下所示:

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"

文档说我无法设置绑定属性的值:

prop0.value = "foo" // exception

虽然我可以有循环绑定:

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

prop0.bindBidirectional(prop1)
prop1.bindBidirectional(prop2)
prop2.bindBidirectional(prop0)

但是一个简单的双向绑定会产生一个StackOverflowError:

prop0.bindBidirectional(prop1)
prop1.bindBidirectional(prop0)

这就是为什么(我猜)有一种明确的方式来进行双向绑定

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

prop0.bindBidirectional(prop1)
prop0.bindBidirectional(prop2)

我不明白为什么 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)

但是让我创建任意数量的BidirectionalBindings?当一个双向绑定应该是两个单向绑定时,为什么这些概念之间存在差异?

还有点奇怪的是Binding 接口创建了一个新实体,该实体将依赖于源ObservableValues:

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)

可以是disposed:

sum.dispose()

但是当我调用bindbindBidirectional 时,它不会返回一次性Binding

我阅读了文档,但其中没有解释这些内容。我错过了什么?使这种行为成为必要的内部逻辑是什么?

【问题讨论】:

  • 您使用的是什么版本的 JavaFX?我在 JavaFX 11 中没有得到 StackOverflowError

标签: java javafx data-binding kotlin


【解决方案1】:

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

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

a.bindBidirectional(b);
...
a.unbindBidirectional(b);

这会处理“处置”。

与属性之间的绑定相比,绑定对象是依赖于一些Observables 的ObservableValue 对象。绑定对象自动将InvalidationListeners 注册到它的依赖项中,但是由于不再使用绑定对象,因此依赖项无法知道可以删除此侦听器。这就是为什么绑定对象允许您在不再需要它时通过调用它的dispose 方法来进行“清理”。

【讨论】:

  • 所以StackOverflowError 是一个错误?我应该举报吗?
  • 我以为我在某处读到过你不应该进行循环双向绑定,但也许那不是官方来源,所以我不确定。
猜你喜欢
  • 2012-01-07
  • 1970-01-01
  • 2016-10-07
  • 2011-07-20
  • 2013-04-02
  • 1970-01-01
  • 2014-08-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多