2016-01-25 1 views
0

Я строю настраиваемую форму в bacon.js. У меня проблема с необязательными полями, которые могут быть пустыми, например. телефон иногда требуется, а иногда и необязательно.Дополнительные поля в форме baconjs

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) 
+0

так почему 'rxjs' тег? – user3743222

ответ

0

С текущего кода я должен был что-то типа в каждом входе. Мое понимание Bacon.when( [data_prop, submit_stream] будет сгореть, если data_prop не пуст. И мы принимаем submit_stream событие. Почему data_prop не оценен? Я считаю, что Bacon.combineTemplate не будет создавать свойство со значением, если у всех value_stream не было события.

Я преобразованный поток в опору со значением по умолчанию

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

Это решило проблему? Я до сих пор не совсем уверен, какая именно проблема здесь :) – raimohanska

+0

Мое понимание bacon.js ограничено, но я обновил ответ. –

+1

Таким образом, проблема заключалась в том, что некоторые свойства, представляющие значения ваших входов, не имели значения (потому что не было входных событий), и, следовательно, combTemplate, очевидно, тоже не имеет значения. Вы добавили значение по умолчанию в свойства и теперь оно работает. Задача решена? – raimohanska