我正在努力使我的头变得苗条的3反应性...
我想在单击按钮时强制刷新UI。我正在使用自定义组件AsyncFetcher
,该组件接受HTTP发布数据,并为其插槽返回data
对象(http发布结果)。
我想具有禁用功能。因此,当单击“禁用”按钮时,将调用http api,然后刷新数据视图。
<script>
export let id
function onDisable() {
fetch('disable-api-url', {id: id})
// Then ??
// What to do after the fetch call, to refresh the view
}
</script>
<AsyncFetcher postParam={id} let:data>
{data.name}
<button on:click={??}>Refresh</button>
<button on:click={onDisable}>Disable Item</button>
</AsyncFetcher>
我尝试做on:click={() => id=id}
来欺骗它以刷新为无效。如果id
应该是对象而不是字符串id={...id}
可以工作,那么不幸的是,这里不是这种情况。
实现此目标的正确方法是什么?
答案 0 :(得分:2)
使用组件来管理提取非常不常规。通常,您可以在onMount
内部或事件处理程序中获取数据:
<script>
import { onMount } from 'svelte';
let initialData;
let otherData;
onMount(async () => {
const res = await fetch('some-url');
initialData = await res.json();
});
async function update() {
const res = await fetch('some-other-url');
otherData = await res.json();
}
</script>
{#if initialData}
<p>the data is {initialData.something}</p>
{/if}
<button on:click={update}>update</button>
答案 1 :(得分:1)
就我而言,svelte 没有刷新输出,
因为我通过以 100% cpu 运行基准来阻止 javascript 事件循环
在这种情况下,诀窍是使用 await sleep(10)
<script>
function sleep(millisec = 0) {
return new Promise((resolve, reject) => {
setTimeout(_ => resolve(), millisec);
});
};
let result = '';
async function runBenchmark() {
for (let step = 0; step < 10; step++) {
// this needs 100% cpu, so no time for svelte render
cpuburn(); result += `${step}: 1.234 sec\n`;
// unblock the JS event loop, so svelte can render
await sleep(10);
}
}
</script>
<pre>{result}</pre>
here 是一个 repl(但目前它在 repl 运行时触发了一个错误)
用同步函数调用解决这个问题可能是不可能的
(类似于 $$svelte.forceTickSync()
)
答案 2 :(得分:0)
尽管Rich Harris提供了一个完全可服务的答案,但这是一种强制Svelte更新组件以反映其数据(also posted here的外部更改的解决方案。
>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!
函数中根据需要进行任意细化,这样只有要同步的片段才可以。