Cyclejs ввод не сбрасывается после перерисовки
Я пытался создать простое приложение todo с Cyclejs/xstream
, Приложение работает отлично. Единственное, что я не могу понять, это то, что после добавления каждого задания ввод должен быть очищен, чего не происходит.
todo.js
import {
div, span, p, input, ul, li, button, body
}
from '@cycle/dom'
import xs from 'xstream'
import Utils from './utils'
export function Todo(sources) {
const sinks = {
DOM: view(model(intent(sources)))
}
return sinks
}
function intent(sources) {
return {
addTodo$: sources.DOM.select('input[type=text]').events('keydown').filter((ev) => {
return ev.which == 13 && ev.target.value.trim().length > 0;
}).map((ev) => {
return ev.target.value;
}),
deleteTodo$: sources.DOM.select('.delete').events('click').map((ev) => {
return Number(ev.target.getAttribute('data-id'));
}).filter((id) => {
return !isNaN(id);
}),
completeTodo$: sources.DOM.select('.complete').events('click').map((ev) => {
return Number(ev.target.getAttribute('data-id'));
}).filter((id) => {
return !isNaN(id);
})
};
}
function model(action$) {
let deleteTodo$ = action$.deleteTodo$.map((id) => {
return (holder) => {
let index = Utils.findIndex(holder.currentTodos, 'id', id);
if (index > -1) holder.currentTodos.splice(index, 1);
return {
currentTodos: holder.currentTodos,
value: ''
};
};
});
let completeTodo$ = action$.completeTodo$.map((id) => {
return (holder) => {
let index = Utils.findIndex(holder.currentTodos, 'id', id);
if (index > -1) holder.currentTodos[index].completed = !holder.currentTodos[index].completed;
return {
currentTodos: holder.currentTodos,
value: ''
};
};
});
let addTodo$ = action$.addTodo$.map((item) => {
return (holder) => {
let todo = {
value: item,
id: holder.currentTodos.length + 1,
completed: false
};
holder.currentTodos.push(todo);
return {
currentTodos: holder.currentTodos,
value: ''
};
};
});
return xs.merge(deleteTodo$, addTodo$, completeTodo$)
.fold((holder, modifier) => {
return modifier(holder);
}, {
currentTodos: [],
value: ''
});
}
function view(state$) {
return state$.map((state) => {
console.log(state);
return div({
attrs: {
class: 'todo'
}
}, [
input({
props: {
type: 'text',
value: state.value
}
}),
ul({
attrs: {
class: 'text'
}
}, state.currentTodos.map((todo) => {
return li({
attrs: {
class: `${todo.completed ? 'completed' : 'open'}`
}
}, [
span(todo.value),
button({
attrs: {
class: 'delete',
'data-id': todo.id
}
}, 'XXXXX'),
button({
attrs: {
class: 'complete',
'data-id': todo.id
}
}, 'CCCCC')
]);
}))
]);
});
}
utils.js
var Utils = {
filter: function(array, fn) {
var results = [];
var item;
for (var i = 0, len = array.length; i < len; i++) {
item = array[i];
if (fn(item)) results.push(item);
}
return results;
},
findItem: function(array, fn) {
for (var i = 0, len = array.length; i < len; i++) {
var item = array[i];
if (fn(item)) return item;
}
return null;
},
findIndex: function(array, prop, value) {
var pointerId = -1;
var index = -1;
var top = array.length;
var bottom = 0;
for (var i = array.length - 1; i >= 0; i--) {
index = bottom + (top - bottom >> 1);
pointerId = array[index][prop];
if (pointerId === value) {
return index;
} else if (pointerId < value) {
bottom = index;
} else if (pointerId > value) {
top = index;
}
}
return -1;
}
};
export default Utils;
1 ответ
Решение
Вам нужно положить крючок внутри элемента ввода. Это будет работать как ожидалось. Если вы хотите, вы можете отправить другое значение по умолчанию (в данном случае это пустая строка).
input({
props: {
type: 'text'
},
hook: {
update: (o, n) => n.elm.value = ''
}
}),
Драйвер @cycle/dom должен быть> 11.0.0, который работает со Snabbdom. Но если вы используете более раннюю версию, вам нужно:
var Hook = function(){
this.arguments=arguments;
}
Hook.prototype.hook = function(node) {
node.value=this.arguments[0];
}
input({ attributes: {type: 'text'},
'my-hook':new Hook('')
})