Básicamente, estoy jugando con Svelte tratando de activar una aplicación rápida, los detalles de la aplicación no son importantes, pero básicamente alberga un montón de sitios integrados. ver ejemplo aquí y para la replicabilidad:
https://svelte.dev/repl/6f3484554ef8489b9a5960487a0a1f95?version=3.47.0
Mi problema es que cuando agrego una nueva URL y título a la lista de sitios, el bloque {#each} que crea las vistas incrustadas no se actualiza para reflejar el nuevo estado de la lista, aunque la lista se actualiza claramente en el salida de la consola. ¿Tiene algo que ver con el alcance o es un problema de Svelte de no activar la reactividad en las reasignaciones de accesorios de los componentes?
Actualización: algunos sitios no permiten la incrustación, así que use https://wikipedia.org como un sitio seguro para realizar pruebas.
si reemplaza una URL codificada en la lista de sitios con la dirección wiki, debería funcionar bien. básicamente quiero que aparezca una nueva ventana ya que el bloque {#each} crea un nuevo componente SiteView
Hay varios problemas con su código, el primero es que no propaga los cambios realizados en la matriz de sites a la aplicación principal, debe usar bind: para mantener las dos matrices sincronizadas.
<InputBar bind:sites {site} />La segunda es que está modificando un objeto cuando agrega un nuevo sitio y luego agrega ese objeto a la matriz, este siempre será el mismo objeto, por lo que si lo cambia, los sitios agregados anteriormente también cambiarán. Puede resolver esto distribuyendo el nuevo objeto en la matriz en su lugar:
function add() { sites = sites.concat({...site}); console.log(sites)} // or alternatively function add() { sites = [...sites, {...site}]; console.log(sites); }Dicho esto, la aplicación no es muy "Svelte" , ya que mezcla responsabilidades y expone datos a componentes que no necesitan esos datos. Por ejemplo, ¿por qué la barra de entrada necesita saber acerca de los sitios actuales? Sería mucho mejor que la barra de entrada fuera solo eso, una barra de entrada. Cuando el usuario hace clic en 'agregar', genera un evento que dice 'algo se ha agregado' y restablece los campos. Luego, el padre es responsable de agregarlo a la matriz. Esto hará que la solución sea más flexible. Si lo hace, verá que tampoco hay razón para tener una variable de 'sitio' en el nivel superior (o incluso tener ese objeto, solo puede tener dos campos)
<script> import { createEventDispatcher } from 'svelte' let url = '' let title = '' const dispatch = createEventDispatcher() function add() { dispatch('add', { url, title }) url = '' title = '' } </script> <div class="rounded"> <p>Enter a site to stream:</p> <input type="text" placeholder="www.example.com" bind:value={url}> <br> <input type="text" placeholder="example" bind:value={title}> <button on:click={add}>add</button> </div> <InputBar on:add={(ev) => sites = [...sites, ev.detail]} /> En una nota final, para agregar cosas al encabezado del html, use <svelte:head> en su lugar.