Javascript baconjs表单中的可选字段

Javascript baconjs表单中的可选字段,javascript,stream,reactive-programming,rxjs,bacon.js,Javascript,Stream,Reactive Programming,Rxjs,Bacon.js,我正在bacon.js中构建可定制表单。我对可选字段有问题,这些字段可以是空的,例如电话有时是必需的,有时是可选的 field_events = _.merge( _.mapValues(@form, @_build_field_streams), dynamic_field_events ) valid_streams = _.pluck(_.values(field_events), 0) all_invalid = Bacon.all(valid_streams).not().toPr

我正在bacon.js中构建可定制表单。我对可选字段有问题,这些字段可以是空的,例如电话有时是必需的,有时是可选的

field_events = _.merge(
  _.mapValues(@form, @_build_field_streams), dynamic_field_events
)
valid_streams = _.pluck(_.values(field_events), 0)
all_invalid = Bacon.all(valid_streams).not().toProperty()

data_prop = Bacon.combineTemplate(
  _.mapValues(field_events, ([is_valid, value_stream]) -> value_stream)
)

submit_stream = @$el
  .asEventStream('click', @submit_selector)
  .doAction(".preventDefault")
  .alwaysSkipWhile(all_invalid)

@actions = Bacon.when(
  [data_prop, submit_stream],
  (data) -> {action: 'submit', param: data}
)
data_prop是惰性评估的,所以如果电话流没有任何值,我们就不会提交表单。有没有办法给流一个默认值或从
combineTemplate
中过滤空流

代码的其余部分:

_build_field_streams: ({selector, validator}, field) =>
value_stream = Bacon.mergeAll(
  @_get_field_change_streams(selector)
).map((e) ->
  $(e.currentTarget).val()
)

if _.isString validator
  validator = exports.validators[validator]()

# optional field are valid by default and for empty values
is_optional_field = field not in @mandatory_field
curr_validator = validator || @noop_validator
validator_fun = (x) -> if is_optional_field and not x
  return true
else
  return curr_validator(x)
validator_stream = value_stream.map(validator_fun)

is_valid = validator_stream.map(_.isEmpty).toProperty(is_optional_field).log('field')

[ok_events, bad_events] = validator_stream.split(_.isEmpty)
bad_events = bad_events.debounce(@invalid_delay)

defocus = @$el.asEventStream('blur', selector)

# TODO: Might be good to instantly go bad _if_ it was already valid.
Bacon.when(
  [ok_events],            true
  [is_valid, bad_events], ((valid) -> valid),
  [is_valid, defocus],    ((valid) -> valid)
).onValue( (valid) =>
  if valid
    @render_field_valid(selector)
  else
    @render_field_invalid(selector)
)
return [is_valid, value_stream]

_get_field_change_streams: (selector) ->
  # Hopefully these 2 cover most things.  Can always add more if we need.
  return _.map ['change', 'keyup'], (handler) =>
    @$el.asEventStream(handler, selector)

使用当前代码,我必须在每个输入中键入一些内容。我的理解是
Bacon.when([data\u prop,submit\u stream]如果
data\u prop
是非空属性,并且我们收到
submit\u stream
事件,那么
将触发。为什么
data\u prop
没有评估?我相信
Bacon。除非所有
value\u stream
都有事件,否则combineTemplate
不会创建具有值的属性

我将流转换为具有默认值的道具

data_prop = Bacon.combineTemplate(
  _.mapValues(field_events, ([is_valid, value_stream]) -> value_stream.toProperty(''))
)

那么为什么使用
rxjs
标记呢?这解决了你的问题吗?我仍然不太确定你的确切问题是什么:)我对bacon.js的理解有限,但我更新了答案。所以问题是,一些表示输入值的属性没有值(因为没有输入事件)因此combineTemplate显然也没有值。您为属性添加了一个默认值,现在可以使用了。问题解决了吗?