Как сбросить поля формы до значения по умолчанию в cycle.js
У меня есть кусок кода, использующий cycle.js и реактивную библиотеку xstream, как показано ниже. Он состоит из поля формы, значение которого отображается в теге ap при отправке. Далее следуют вопросы: 1. Как можно изменить поле ввода формы на значение по умолчанию при отправке формы? 2. Есть ли способ сбросить input$ и отправить $ streams к их начальным значениям после submit?
function formIntent (sourcesDOM) {
const fNameInput$ = sourcesDOM
.select('form#user .fname')
.events('input')
.compose(debounce(1000))
.map((e: {target: any}) => e.target.value)
const submit$ = sourcesDOM
.select('form#user')
.events('submit')
.map((e) => e.preventDefault())
.mapTo({type: 'USER'})
const actions$ = xs.combine(fNameInput$, submit$)
const initState = {fNameInput: ''}
return actions$
.map(([fNameInput, {type}]) => {
return type === 'USER' ? {fNameInput} : initState
})
.startWith(initState)
}
function formView (state$) {
return state$
.map(({fNameInput}) =>
div([
form('#user', [
label('Name'),
hr(),
input('.fname', {attrs: {id: 'first-name', type: 'text', placeholder: 'First name'}}),
hr(),
input('.sub', {attrs: {type: 'submit', value: 'Save'}})
]),
div([
h2('Submitted value'),
p(fNameInput),
hr()
])
])
)
}
Есть ли лучший способ создать такую форму? PS вывод функции formIntent подается на вход функции formView.
2 ответа
Вы можете использовать ловушку для обновления входного значения при обновлении DOM. Так что если вы используете @cycle/dom version >11.0, которая использует Snabbdom, вы можете использовать это так:
input({
hook: {
update: (o, n) => n.elm.value = ''
}
})
Где пустая строка, вы можете передать значение по умолчанию, которое вы хотите. Он будет обновлять входное значение каждый раз, когда состояние обновляется.
Это то, что я в итоге сделал. Это делает то, что я хотел. Мне все еще будет интересно узнать лучший способ достижения той же цели.
function formIntent (sourcesDOM) {
const fNameInput$ = sourcesDOM
.select('form#user .fname')
.events('input')
.compose(debounce(1000))
.filter((e: {target: any}) => e.target.value.length > 2)
.map((e: {target: any}) => e.target)
const submit$ = sourcesDOM
.select('form#user')
.events('submit')
.map(e => {
e.preventDefault()
console.log('3: Inside intent', e)
return {user: 'CLICKED'}
})
return xs.combine(fNameInput$, submit$)
}
function formModel (actions$) {
const initState = {user: '', fNameInput: {}}
return actions$
.map(([fNameInput, user]) => {
const fName = fNameInput.value
if (user.user === 'CLICKED') {
fNameInput.value = fNameInput.defaultValue
user.user = 'DISPLAY'
return {user: user.user, fNameInput: fName}
} else return initState
})
.startWith(initState)
}
function formView (state$) {
return state$
.map(({user, fNameInput}) =>
div([
form('#user', [
label('Name'),
hr(),
input('.fname', {attrs: {id: 'first-name', type: 'text', placeholder: 'First name'}}),
hr(),
input('.sub', {attrs: {type: 'submit', value: 'Save'}})
]),
(user === 'DISPLAY') && div([
h2('Submitted value'),
p(fNameInput),
hr()
])
])
)
}
function main (sources) {
const actions$ = formIntent(sources.DOM)
const state$ = formModel(actions$)
const vtree$ = formView(state$)
return {
DOM: vtree$
}
}