简体   繁体   English

在 Svelte 中,您可以使用 `array = array` 在视图中将数组标记为需要刷新吗?

[英]In Svelte, you can use `array = array` to mark the array as needing a refresh in the view?

That is, using也就是说,使用

array = array;

to trigger the view to refresh with the current array ?触发视图以当前array刷新?

For example, the following uses例如,以下使用

cards = [...cards, {name}];

to "add" an entry to the array cards , but by assigning cards to a new array, and cards in the view will be refreshed. “添加”一个条目到数组cards ,但通过将cards分配给新数组,视图中的cards将被刷新。

sample on: https://svelte.dev/repl/3ed20e7bac2e4b65944c98485d9217b3?version=3.18.1示例: https : //svelte.dev/repl/3ed20e7bac2e4b65944c98485d9217b3?version=3.18.1
(just type in some names and the list below will update). (只需输入一些名称,下面的列表就会更新)。

However, this is O(n²) when entering n names, because each time, the creation of a new array is O(n).但是,输入n名字时这是O(n²),因为每次创建一个新数组都是O(n)。 If (1) the user is expected to enter a few or a dozen name at a time, it is not such a big problem, or (2) the user may type a name for a few seconds up to 20 seconds, then any delay of the UI for 0.2 seconds isn't a big problem when the entry is up to 1000 or 2000 names.如果 (1) 预计用户一次输入几个或十几个名字,这不是什么大问题,或者 (2) 用户可能会输入一个名字几秒到 20 秒,那么任何延迟当条目多达 1000 或 2000 个名称时,0.2 秒的 UI 不是一个大问题。 (the user probably will be better to add to the server and database just in case of power outage anyways.) (用户可能会更好地添加到服务器和数据库,以防万一断电。)

But in case we don't want the O(n²) time, we could also use:但如果我们不想要 O(n²) 时间,我们也可以使用:

    cards.push({name});
    cards = cards;

this will trigger a refresh in the view.这将触发视图中的刷新。 So Svelte doesn't do "dirty checking"?所以 Svelte 不做“脏检查”? Is it true that compared to Angular, Vue, and React, they do dirty checking by actually converting the array to a string and check whether the array has changed?是不是与 Angular、Vue 和 React 相比,它们通过将数组实际转换为字符串并检查数组是否已更改来进行脏检查?

sample: https://svelte.dev/repl/70cc3b08f6864ef387c691b8f126a7fd?version=3.18.1示例: https : //svelte.dev/repl/70cc3b08f6864ef387c691b8f126a7fd?version=3.18.1

Without the line cards = cards;没有线cards = cards; , the list won't get updated in the view: ,该列表不会在视图中更新:

sample: https://svelte.dev/repl/25f41c51798d425e805fb4586a843363?version=3.18.1示例: https : //svelte.dev/repl/25f41c51798d425e805fb4586a843363?version=3.18.1

So Svelte doesn't do actually dirty checking but use the cards = something;所以 Svelte 实际上并不做脏检查,而是使用cards = something; as a hint that cards has changed, even by cards = cards ?作为cards已经改变的暗示,即使是cards = cards So can we just use this as a general technique to mark something as dirty if we use array.push() so that the program can run faster?那么,如果我们使用array.push()以便程序可以运行得更快,我们是否可以将其array.push()将某些内容标记为脏的通用技术? Could Svelte actually guess that cards has changed by detecting there is a cards.push() statement? Svelte 真的可以通过检测到cards.push()语句来猜测cards已经改变了吗?

Update: it was found that by adding a key to each list item, cards = cards is not needed, and I am wondering why:更新:发现通过为每个列表项添加一个键,不需要cards = cards ,我想知道为什么:

https://svelte.dev/repl/d78158ae54684bf28b8c2e9b527f1915?version=3.18.1 https://svelte.dev/repl/d78158ae54684bf28b8c2e9b527f1915?version=3.18.1

<ul>
  {#each cards as card, i (i)}
    <li>{card.name}</li>
  {/each}
</ul>

Assigning a variable to itself is a hint to the compiler that the relevant parts of the view need to be updated — see here for more information .为自身分配一个变量是对编译器的一个提示,即视图的相关部分需要更新——有关更多信息,请参见此处 It's designed to allow you to work with mutable objects and arrays where necessary for performance, but to nudge you towards using immutable data structures since that will generally result in fewer bugs.它旨在允许您在性能需要时使用可变对象和数组,但会促使您使用不可变数据结构,因为这通常会导致更少的错误。

Detecting things like array.push(...) isn't really practical — it's much better to have a single, clear way of telling the compiler 'this has changed', and the assignment operator is that way.检测像array.push(...)这样的东西并不是很实用——有一个单一的、清晰的方法告诉编译器“这已经改变了”,赋值运算符就是这样。

The reason it works with the keyed each block but not the unkeyed one is actually due to a bug — I've raised an issue: https://github.com/sveltejs/svelte/issues/4373它适用于带键的每个块而不是不带键的块的原因实际上是由于错误 - 我提出了一个问题: https : //github.com/sveltejs/svelte/issues/4373

You can use custom stores to emulate "detecting changes caused by push() method".您可以使用自定义存储来模拟“检测由push()方法引起的更改”。

See this REPL by Rich Harris https://svelte.dev/repl/2699eb0fe7dd4621b3e585aec1a30d01?version=3.17.3查看 Rich Harris 的这个 REPL https://svelte.dev/repl/2699eb0fe7dd4621b3e585aec1a30d01?version=3.17.3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM