我有2个Bacon.jQuery Models
(但问题可以用任何培根Observable
来说明。)
我有3个组合框:foo
,bar
和quux
。 bar
取决于foo
和quux
取决于bar
和quux
的组合。有一个findQuux
函数可以从quux
和foo
找到bar
组合框的值。
如果用户更改foo
组合框,则会选中bar
和quux
框中的值。以下是quux
选择的工作实现:
// WORKS
var quuxBus = new Bacon.Bus()
Bacon.onValues(fooModel, barModel, function (foo, bar)
{
quuxBus.push(findQuux(foo, bar))
})
quuxModel.addSource(quuxBus.toProperty('quux4'))
此解决方案存在一些问题,因为我需要'quux4'
黑客在页面加载时正确设置quux
。但是以下更简单的解决方案根本不起作用:
// DOESN'T WORK
var quuxCombo = Bacon.combineWith(findQuux, fooModel, barModel)
quuxModel.addSource(quuxCombo)
问题在于,findQuux
需要foo
和bar
的有效组合,并且在使用无法找到quux
的不可能组合时会崩溃。
onValues/push
解决方案有效,因为findQuux
仅在用户更改foo
组合框时被调用一次。 bacon.combineWith
解决方案不起作用,因为findQuux
被调用两次。
为quuxModel
实施数据源的推荐方法是什么?防御性地编码findQuux
不是一种选择。
完整代码可在http://jsfiddle.net/5zp4D/8/
找到 更新:页面加载中foo
和bar
已有合理的值。从小提琴链接fooModel
可以看出,使用显式值进行初始化,并从该初始值重新计算barModel
:
var fooModel = Bacon.$.selectValue(fooDom, 'foo2-value')
var barModel = Bacon.$.selectValue(barDom)
barModel.addSource(fooModel.map(function (x)
{
return json[x][1].val
}))
foo
和bar
从不接受无效值。此外,一旦用户更改bar
,foo
就会重新填充,因此在用户界面中只能看到有效的组合。
combineWith
方法的问题是当用户切换foo
时,findQuux
函数被调用两次中间值,其中一个中间组合不正确,而组合成分是分开正确的。我改变了小提琴以更好地说明问题:http://jsfiddle.net/5zp4D/12/
从var json
可以看出,有效组合是1-1,1-2,2-3,2-4和2-5。
我取消了破损版本的注释,添加了日志记录。当您选择foo1
然后在第一个组合框中选择返回foo2
时,您会在日志中收到4条消息而不是3条消息:
在页面加载时,您会看到quux
值已正确初始化(2-4):
"valid combination of foo2-value and bar4-value"
当您选择foo1
而不是foo2
时,您会看到findQuuxDef
被调用1-4(foo
是新的,bar
是旧的)并且那么2-4(foo
是新的,bar
是新的):
"invalid combination of foo1-value and bar4-value"
"valid combination of foo1-value and bar2-value"
我的问题是使用onValues/push
方法不会发生无效的中间组合,我想知道什么是使用链接元素的UI的惯用推荐方法。
答案 0 :(得分:1)
我首先让quuxCombo
仅输出findQuux
的有效值。我希望从页面加载中获得输入foo
和bar
的合理值,但如果这不可能(为什么不呢?),我会在输入上使用filter
。例如,
var quuxCombo = Bacon.combineWith(findQuux, fooModel.filter(validFoo), barModel.filter(validBar))
我想,你想在有效输入存在之前先用一些初始值开始。为此,我在Bacon.js 0.6.15中添加了一个新方法Property.startWith
。那么,现在你可以
var quuxCombo = Bacon.combineWith(findQuux, fooModel.filter(validFoo), barModel.filter(validBar)).startWith("quux4")