我有 2 Bacon.jQuery Models
(但问题可以用任何 Bacon 来说明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'
hack 才能quux
在页面加载时正确设置。但是以下更简单的解决方案根本不起作用:
// DOESN'T WORK
var quuxCombo = Bacon.combineWith(findQuux, fooModel, barModel)
quuxModel.addSource(quuxCombo)
问题在于,当输入一个无法找到 a 的不可能组合时,它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
,就会重新填充,因此在 UI 中只能看到有效的组合。
方法的问题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 的惯用推荐方法是什么。