- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我经常发现自己遇到问题,即控件的两个(相关)值被更新,并且两者都会触发昂贵的操作,或者控件可能会暂时处于不一致的状态。
例如,考虑一个数据绑定(bind),其中两个值 (x,y) 相互减去,最终结果用作某个其他属性 z 的除数:
z/(x - y)
如果 x 和 y 绑定(bind)到某个外部值,那么一次更新它们可能会导致意外除以零错误,这取决于首先更新哪个属性以及另一个属性的旧值是什么。更新属性 z 的代码只是监听 x 和 y 的变化——它无法提前知道另一个属性的另一个更新即将到来。
现在这个问题很容易避免,但是还有其他类似的情况,比如设置宽度和高度......我是立即调整窗口大小还是等待另一个更改?我是立即为指定的宽度和高度分配内存还是等待?如果宽度和高度是 1 和 100 万,然后更新为 100 万和 1,那么暂时我将有 100 万 x 100 万的宽度和高度......
这可能是一个相当普遍的问题,尽管对我来说它特别适用于 JavaFX 绑定(bind)。我感兴趣的是如何处理这些情况,而不会遇到未定义的行为或执行昂贵的操作,一旦另一个绑定(bind)发生变化就需要重做。
到目前为止,为了避免这些情况,我所做的事情是在设置新值之前首先清除与已知值的绑定(bind),但这对更新绑定(bind)的代码来说是一个负担,它确实不需要知道。
最佳答案
我现在才学习 JavaFX,所以对这个答案持保留态度......欢迎任何更正。我对此很感兴趣,所以做了一些研究。
失效监听器
这个问题的部分答案是 InvalidationListener
.您可以详细阅读文档 here , 但本质是一个 ChangeLister
立即传播更改,而 InvalidationListener
注意到一个值是无效的,但会推迟计算直到需要它。基于“z/(x - y)”计算的两种情况的示例:
首先,琐碎的东西:
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.binding.NumberBinding;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableNumberValue;
import javafx.beans.value.ObservableValue;
public class LazyExample
{
public static void main(String[] args) {
changeListenerCase();
System.out.println("\n=====================================\n");
invalidationListenerCase();
}
...
}
x
,
y
,
z
, 计算表达式
z / (x - y)
和适当的听众。然后他们调用
manipulate()
改变值的方法。记录所有步骤:
public static void changeListenerCase() {
SimpleDoubleProperty x = new SimpleDoubleProperty(1);
SimpleDoubleProperty y = new SimpleDoubleProperty(2);
SimpleDoubleProperty z = new SimpleDoubleProperty(3);
NumberBinding nb = makeComputed(x,y,z);
nb.addListener(new ChangeListener<Number>() {
@Override public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
System.out.println("ChangeListener: " + oldValue + " -> " + newValue);
}
});
// prints 3 times, each after modification
manipulate(x,y,z);
System.out.println("The result after changes with a change listener is: " + nb.doubleValue());
}
public static void invalidationListenerCase() {
SimpleDoubleProperty x = new SimpleDoubleProperty(1);
SimpleDoubleProperty y = new SimpleDoubleProperty(2);
SimpleDoubleProperty z = new SimpleDoubleProperty(3);
NumberBinding nb = makeComputed(x,y,z);
nb.addListener(new InvalidationListener() {
@Override public void invalidated(Observable observable) {
System.out.println("Invalidated");
}
});
// will print only once, when the result is first invalidated
// note that the result is NOT calculated until it is actually requested
manipulate(x,y,z);
System.out.println("The result after changes with an invalidation listener is: " + nb.doubleValue());
}
private static NumberBinding makeComputed(final ObservableNumberValue x, final ObservableNumberValue y, final ObservableNumberValue z) {
return new DoubleBinding() {
{
bind(x,y,z);
}
@Override protected double computeValue() {
System.out.println("...CALCULATING...");
return z.doubleValue() / (x.doubleValue()-y.doubleValue());
}
};
}
private static void manipulate(SimpleDoubleProperty x, SimpleDoubleProperty y, SimpleDoubleProperty z) {
System.out.println("Changing z...");
z.set(13);
System.out.println("Changing y...");
y.set(1);
System.out.println("Changing x...");
x.set(2);
}
...CALCULATING...
Changing z...
...CALCULATING...
ChangeListener: -3.0 -> -13.0
Changing y...
...CALCULATING...
ChangeListener: -13.0 -> Infinity
Changing x...
...CALCULATING...
ChangeListener: Infinity -> 13.0
The result after changes with a change listener is: 13.0
=====================================
...CALCULATING...
Changing z...
Invalidated
Changing y...
Changing x...
...CALCULATING...
The result after changes with an invalidation listener is: 13.0
infinity
案子。在第二种情况下,数据在第一次更改时被标记为无效,然后仅在需要时重新计算。
width = lengthyComputation();
Platform.runLater(node.setWidth(width));
height = anotherLengthyComputation();
Platform.runLater(node.setHeight(height));
width = lengthyComputation();
height = anotherLengthyComputation();
Platform.runLater(node.setWidth(width));
Platform.runLater(node.setHeight(height));
javafx.scene.Parent
的某些方法。每个脉冲运行一次并达到相同的效果。所以你要么扩展
layoutChildren()
,如果不需要更改子树或
computePrefHeight(double width)
中的任何一个/
computePrefWidth(double height)
, 如果子树将被修改。
关于binding - 如何处理相关的数据绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19749389/
我不知道该怎么做... function f1() { var x = 10; function f2(fx) { var x; x = 6;
早期绑定(bind)和后期绑定(bind)有什么区别? 最佳答案 简短的回答是,早期(或静态)绑定(bind)是指编译时绑定(bind),后期(或动态)绑定(bind)是指运行时绑定(bind)(例如
如何在 SwiftUI View 上使用 Binding(get: { }, set: { }) 自定义绑定(bind)与 @Binding 属性。我已成功使用此自定义绑定(bind)与 @State
我经常发现自己遇到问题,即控件的两个(相关)值被更新,并且两者都会触发昂贵的操作,或者控件可能会暂时处于不一致的状态。 例如,考虑一个数据绑定(bind),其中两个值 (x,y) 相互减去,最终结果用
我想通过我的 ViewModel 控制我的一个窗口的高度和宽度。 这看起来很简单。 但没有。它不起作用。 它检查 ViewModel 的 Width但不是 Height . 奇怪的是,如果我切换 W
UI5中一次性绑定(bind)和单向绑定(bind)有什么区别? 是否有任何用户特定的用例我会使用它们? 我无法从文档中获得太多信息。 最佳答案 单程 它的作用:单向数据流。模型数据的变化(例如通过
(define make (lambda (x) (lambda (y) (cons x (list y))))) (let ((x 7) (p (make 4))) (cons
尽管我或多或少地了解什么是语言绑定(bind),但我很难理解它们是如何工作的。 例如,谁能解释一下如何为 WinAPI 制作 Java 绑定(bind)? 最佳答案 如果您搜索 Foreign Fun
谁能解释为什么我可以重新绑定(bind)列表但不能+? (binding [list vector] (list 1 3)) (binding [list +] (list 1 3)) (bi
我真的很喜欢 Caliburn 和命名约定绑定(bind),我很惊讶 可见性与“CanNAME”约定用于保护 Action 的方式不同。 据我所知, BooleanToVisibilityConver
我了解动态绑定(bind)的实现方式以及静态绑定(bind)和动态绑定(bind)之间的区别,但我只是无法理解动态绑定(bind)的定义。基本上它是一种运行时绑定(bind)类型。 最佳答案 基本上,
http://jsfiddle.net/3NRsd/ var foo = $("div").bind("click", function() { $("div").animate({"hei
这个问题我快疯了...我有一个用户控件,它有一个用于插入操作的 FormView 和一个用于所有其他操作的 GridView。 在这两个控件中,我都有一个 DropDownList,如下所示: '
我有一个绑定(bind)到 ListBox 的地址的 ObservableCollection。然后在 ItemTemplate 中,我使用 {Binding .} 绑定(bind)到当前地址记录。这
如果我有以下简单的 js/knockout 代码: .js( View 模型): var image = ko.observable('http://placehold.it/300x150'); 看
我正在 aurelia 上开发一个自定义属性,让用户在输入文本区域时从列表中进行选择。例如,用法将是这样的: 正如您可能注意到的,auto-complete是属性。现在,当我想显示提示时,我想在自定
我正在使用 EventEmitter2作为我的应用程序内部的消息总线。现在我需要绑定(bind)和取消绑定(bind)一些事件处理程序。因为我也希望他们bind将它们添加到给定的上下文中,我最终得到以
我有以下函数调用: $(".selector").on("click", callback.bind(this, param1, param2)); 在我的回调函数中,我想使用绑定(bind)的 th
我目前正在试验新的编译绑定(bind),并且(再次)达到了我在拼图中遗漏了一个小问题:为什么我必须调用 Bindings.Update?直到现在,我还认为实现 INotifyPropertyChang
我正在阅读一本关于编写 JavaScript 框架的书,并找到了这段代码。但是我不明白它是如何工作的,尤其是 bind.bind 的用法?有人知道吗? var bind = Function.prot
我是一名优秀的程序员,十分优秀!