【发布时间】:2016-09-12 06:17:07
【问题描述】:
使用knockout.js computed observables 可以定义一个依赖于其他可观察对象的 JavaScript 可观察对象,使用函数表达式,例如
var computedObservable = ko.computed(function(){
return firtName() + lastName();
});
如果引用的 observable 之一(例如 firstName)发生变化,则计算出的 observable 会自动更新。 引用的 observables 由给定的函数表达式定义,并且不必明确指定。
如何在 Java 中实现类似的功能?
(嗯,有JavaFx Bindings,但它们需要显式注册引用的属性/可观察对象。)
我区分两种情况:
a) 使用 Java 分析给定的 lambda 表达式,以自动找出必须考虑哪些引用的 observable。 (引用的可观察对象可能会引用依赖链中的更多可观察对象。) 预期的示例代码:
ComputedObservable<String> computedObservable = new ComputedObservable<>(() -> {
return firstName.get() + lastName.get();
});
b)我必须手动注册每个引用的 observable 才能观察它们。我想避免这种情况。换句话说,我不想拥有类似
的代码ComputedObservable<String> computedObservable = new CoputedObservable<>();
computedObservable.registerReference(firstName);
computedObservable.registerReference(lastName);
computedObservable.setExpresion(() -> {
return firstName.get() + lastName.get();
});
或(使用JavaFx Bindings)
DoubleBinding db = new DoubleBinding() {
{
super.bind(a, b, c, d);
}
@Override
protected double computeValue() {
return (a.get() * b.get()) + (c.get() * d.get());
}
};
情况 a) 是否可能,如果是,是否有现有的 Java 实现/库可以这样做?
编辑: 还有一种策略:
c) 使用专用运算符 来定义函数表达式。这些运算符隐式地注册了引用的 observables。因此无需额外的手动注册步骤。 (函数表达式将仅限于可用的运算符,并且可能需要高级功能来实现新的帮助运算符。)
StringBinding fullName = firstName.concat(secondName);
DoubleBinding result = a.multiply(b).add(c.multiply(d));
相关问题:
【问题讨论】:
-
请记住,仅仅因为某些东西在 Javascript 中可能有意义并不意味着您应该尝试将其引入 Java。
-
您的疑问是否已经反映在我在回答“注册表策略”时提到的缺点中?或者是否还有其他点会使 knockout.js 的方法无用/不适合 Java?
-
嗯,我的主要观点是,在 Javascript 本身支持类似的东西的地方,Java 中没有类似的机制。这意味着您将努力争取能够以 Javascript 方式编写 Java。这通常表明你做错了什么。就像在 RDBMS 中保存非关系数据一样。
-
很久以前我在 C# 中做过这个。刚刚将它移植到 Kotlin。还是有兴趣?
-
我现在更喜欢 JavaScript 编程。由于 ES5... 甚至不再需要 ko 可观察对象...原则上...,因为可以使用 getter/setter 使属性可观察到它们自己。这被 vue.js 使用:vuejs.org/v2/guide/reactivity.html。不过,您的移植可能对 JVM 的其他用户感兴趣。
标签: java reflection lambda binding observable