我有一个带有输入字段的表单。当我键入(键入)Enter
键时,必须清除这些字段之一。我知道我可以将此字段作为受控字段进行处理(意味着监听keyup
并维护该字段的副本),或者使用双向绑定,但是在我的用例中,我不能做到后者,我宁愿不做前者。因此,我的问题是,如何强制渲染Svelte组件?
通常情况下,表单显示为<Component field="value" />
,用户修改字段并单击Enter
键,我希望app.set(field, value)
将字段重置为value
,即使在斯维尔特(Svelte)眼中,field
属性也没有改变。有可能吗?
我尝试失败的方法是更新Svelte组件的内部属性 ,希望当app.set(field, value)
时,Svelte会看到field
的两个不同值属性并更新组件。但这似乎不起作用:
<script>
const watchForEnter = ev => {
if (ev.keyCode === 13) {
ev.preventDefault();
const formData = new FormData(ev.target.closest("form"));
const tag = formData.get("tag");
dispatch({ [ADDED_TAG]: tag });
}
};
const updateCurrentTag = ev => {
currentTag = new FormData(ev.target.closest("form")).get("tag");
console.log(`currentTag!`, currentTag)
}
</script>
<form>
<fieldset class="form-group">
<input
name="tag"
class="form-control"
type="text"
placeholder="Enter tags"
on:input={updateCurrentTag}
value={currentTag}
on:keyup={watchForEnter} />
</fieldset>
</form>
答案 0 :(得分:1)
我不能完全理解您提供的示例中的所有内容,但是对于您的问题的一般回答是,在Svelte中,您应避免出现需要自己触发更新的情况。
在大多数情况下,可以使您的组件更具声明性,并更好地利用反应性(尤其是反应性语句),使Svelte可以在需要时进行呈现。
但是,在不可能的情况下,作为一种解决方法,您可以滥用{#each ...}
块的键来强制Svelte重新创建通常会被重用的组件。
例如:
<script>
export let allItems
export let currentCategory
$: items = allItems.filter(x => x.category === currentCategory)
</script>
{#each [items] as todos (currentCategory)}
<Todos {todos} />
{/each}
有关更多详细信息,请参见this other answer(复制了上面的示例)。
另请参阅this REPL,其中显示了如何将这种hack实施到可重用的组件中,以使使用者的语法更简洁。
为了完整起见,还出现了this issue,并要求提供此功能。
答案 1 :(得分:0)
我相信我已经找到了一种优雅的解决方案,可以解决在组件数据超出其范围之外时强制组件进行更新的问题。
main.js ;在线示例中的香草,没有特殊更改:
import App from './App.svelte';
var app = new App({
target: document.body
});
export default app;
index.html ;注意window.neek = {...}
:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Svelte app</title>
<script>
window.neek = { nick: true, camp: { bell: "Neek" }, counter: 0 };
</script>
<script defer src='/build/bundle.js'></script>
</head>
<body>
</body>
</html>
App.svelte ;请注意$: notneek = window.neek
和window.neek.update = ...
:
<script>
let name = 'world';
$: notneek = window.neek;
function handleClick() {
notneek.counter += 1;
}
window.neek.update = function () {
notneek = notneek;
}
</script>
<h1>Hello { notneek.camp.bell }!</h1>
<button on:click={handleClick}>
Clicked {notneek.counter} {notneek.counter === 1 ? 'time' : 'times'}
</button>
由于update
函数在App.svelte
的范围内,因此可以在通过window.neek.update()
调用时强制重新渲染。此设置将window.neek.counter
用于按钮使用的内部数据(通过notneek.counter
),并允许在组件外部更新深层属性(例如neek.camp.bell = "ish"
),并在{{ 1}}。
在控制台中,键入neek.update()
并注意window.neek.camp.bell = "Bill"
尚未更新。现在,在控制台中输入Hello Neek!
,UI将会更新为window.neek.update()
。
最重要的是,您可以在Hello Bill!
函数中根据需要进行任意细化,这样只有要同步的片段才可以。