Почему привязки в JavaFX работают так, как они работают? - PullRequest
0 голосов
/ 01 ноября 2018

Я пытаюсь понять, почему привязка данных работает так, как она работает в JavaFX. Это позволяет связывать ObservableValue s с другими ObservableValue 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"

В документах сказано, что я не могу установить значение свойства, которое связано:

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 с? Почему существует различие между этими понятиями, когда двунаправленное связывание должно быть двумя однонаправленными связями?

Также странно, что существует интерфейс 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.

Я читаю документы, но это не объясняется в них. Я что-то пропустил? Какая внутренняя логика делает такое поведение необходимым?

1 Ответ

0 голосов
/ 01 ноября 2018

Свойство привязки a к b означает, что до тех пор, пока привязка «на месте», значение a всегда совпадает со значением b. Для привязки a к c в дополнение к b потребуется, чтобы значение a было таким же, как b и c, но они могли бы содержать разные значения. По этой причине допускается только одна привязка. Отмена привязки объекта автоматически приводит к «удалению».

Двунаправленное связывание приводит к тому, что значения обоих свойств остаются неизменными. Изменение одного обновляет другое, и поэтому вы можете связать свойство с произвольным числом свойств. Если вы изменяете свойство, все другие свойства, которые связаны с ним в двух направлениях, обновляются, а изменение одного из других свойств обновляет само свойство, которое также обновляет все остальные свойства. Здесь нет проблем.
JavaFX решил отменить двустороннее связывание другим способом:

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

Это заботится о «утилизации».

Объекты привязки в отличие от привязок между свойствами - это ObservableValue объекты, которые зависят от некоторых Observable с. Объект привязки автоматически регистрирует InvalidationListener s в своих зависимостях, но у зависимостей нет возможности узнать, что этот прослушиватель может быть удален, поскольку объект привязки больше не используется. Вот почему объект привязки позволяет вам выполнять «очистку», когда он вам больше не нужен, вызывая его метод dispose.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...