使用带有文本字段的 cycle-idb 获取无限循环



我一直在尝试创建一个简单的测试应用程序,该应用程序从文本字段中获取用户输入,显示它,并使用cycle-idb保留它。但无论我做什么,我都会陷入无限循环。

这是整个主要功能:

function intent(domSources) {
return domSources.select('.name')
.events('input')
.map(ev => ev.target.value);
};
function model(input$, db$) {
const log$ = db$;
return xs.combine(input$, log$)
.map(([input, logs]) => {
return {
id: 1,
name: input,
}
}).startWith({id: 1, name: ""});
};
function view(state$) {
return state$.map(log => {
return (
<div>
<label for='name'>Name: </label>
<input 
className='name' 
type='text' 
value={log.name}
placeholder="Enter a log name"
/>
<p>{log.name}</p>
</div>
)
});
};
function persist(state$) {
return state$.map(log => {
return $put('logs', log)
});
};
export function main (sources) {
const db$ = sources.IDB.store('logs').getAll();
const input$ = intent(sources.DOM);
const state$ = model(input$, db$);
const vtree$ = view(state$);
const updateDb$ = persist(state$);
return {
DOM: vtree$,
IDB: updateDb$,
};
}

我正在尝试使用 MVI 并使用 TodoMVC 作为示例,但我无法弄清楚如何在不创建无限循环的情况下管理循环依赖项。

任何建议或指向其他参考资料的指示将不胜感激。

不幸的是,第一个答案会导致数据库的更新流中断。

在 gitter 中,@janat08建议对persist函数进行以下更改,这对我有用

function persist(state$) {
return state$.compose(dropRepeats((x, y) => {
return x.id === y.id && x.name === y.name;
})).map(log => {
return $put('logs', log)
});
};

尚未将其标记为解决方案,因此 Jan 有机会编辑他的解决方案,或者如果有人想出一个不那么黑客的解决方案。

这样做的技巧是使用 dropRepeats 进行深度比较。

来自 gitter 的指向"优化"解决方案的答案:

function model(input$, db$) {
return xs.merge(xs.never(), db$.take(1)).map(name => {
return input$.startWith(name).map(name => {
return { id: 1, name }
})
}).flatten()
};

最新更新