java - 为什么 JavaFX 中的绑定以它们的方式工作?
问题描述
我试图理解为什么数据绑定以它在 JavaFX 中的工作方式工作。它允许您将ObservableValue
s 绑定到其他ObservableValue
s,如下所示:
val prop0 = SimpleStringProperty("xul")
val prop1 = SimpleStringProperty("baz")
prop0.bind(prop1)
当我这样做时,这两个属性都将具有 value 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)
但是让我创建任意数量的BidirectionalBinding
s?当双向绑定应该是两个单向绑定时,为什么这些概念之间存在差异?
同样奇怪的是,有一个Binding
接口创建了一个依赖于源ObservableValue
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
或bindBidirectional
它不返回一次性Binding
.
我阅读了文档,但其中没有解释这些内容。我错过了什么?使这种行为成为必要的内部逻辑是什么?
解决方案
绑定属性a
tob
意味着只要绑定“到位”,其值a
始终与 in of value 相同b
。绑定a
toc
除了b
要求a
' 值与 and 相同b
,c
但它们可以包含不同的值。因此,只允许单个绑定。取消绑定属性会自动处理“处置”。
双向绑定导致两个属性的值保持不变。更改一个会更新另一个,因此您可以将一个属性绑定到任意数量的属性中。如果您更改一个属性,则所有其他双向绑定到它的属性都会更新,并且更改其他属性之一会更新属性本身,这也会更新所有其他属性。这里没问题。
JavaFX 选择以不同的方式解除双向绑定:
a.bindBidirectional(b);
...
a.unbindBidirectional(b);
这负责“处置”。
与属性之间的绑定相比,绑定ObservableValue
对象是依赖于某些Observable
s 的对象。绑定对象自动将InvalidationListener
s 注册到它的依赖项中,但是由于不再使用绑定对象,因此依赖项无法知道可以删除此侦听器。这就是为什么绑定对象允许您在不再需要它时通过调用它的dispose
方法来进行“清理”。
推荐阅读
- php - 错误:当我直接在控制器的构造函数中尝试基于闭包的中间件时,试图获取非对象的属性“标题”。拉拉维尔 6
- c# - 如何空格键单击 DataGridView 一个单元格,在 excel 中打开此数据并删除今天不在 excel 中生成此数据?
- spring - 导入 H2 SQL 脚本时 Spring Batch 不运行
- hyperledger-fabric - 带有密钥的 HyperLedger Fabric 历史交易
- c - c - 应该未定义的动作看起来非常“定义”。为什么?
- ruby - 绕过 Sinatra 中的 not_found 过滤器
- r - 基于R中不同数据框中的索引对列进行求和
- recoll - 如何在 Recoll 中自定义结果?
- ios - 为什么 AVPlayer 初始加载这么慢?
- css - 下拉列表中的短划线类型的文本样式