2020-04-28

Svelte Tutorial 17: Module Context (English & Indonesia)

English


Sharing Code


In all the examples we've seen so far, the <script> block contains code that runs when each component instance is initialised. For the vast majority of components, that's all you'll ever need.

Very occasionally, you'll need to run some code outside of an individual component instance. For example, you can play all five of these audio players simultaneously; it would be better if playing one stopped all the others.

We can do that by declaring a <script context="module"> block. Code contained inside it will run once, when the module first evaluates, rather than when a component is instantiated. Place this at the top of AudioPlayer.svelte:

<script context="module">
  let current;
</script>

<script>
  export let src;
  export let title;
  export let composer;
  export let performer;

  let audio;
  let paused = true;

  function stopOthers() {
    if (current && current !== audio) current.pause();
    current = audio;
  }
</script>

<style>
  article { margin: 0 0 1em 0; max-width: 800px }
  h2, p { margin: 0 0 0.3em 0; }
  audio { width: 100%; margin: 0.5em 0 1em 0; }
  .playing { color: #ff3e00; }
</style>

<article class:playing={!paused}>
  <h2>{title}</h2>
  <p><strong>{composer}</strong> / performed by {performer}</p>

  <audio
    bind:this={audio}
    bind:paused
    on:play={stopOthers}
    controls
    {src}
  ></audio>
</article>

It's now possible for the components to 'talk' to each other without any state management, you just have to create <AudioPlayer> in App.svelte and provide desired properties, the current variable is now shared between all <AudioPlayer>:

<script>
  import AudioPlayer from './AudioPlayer.svelte';
</script>

<!-- https://musopen.org/music/9862-the-blue-danube-op-314/ -->
<AudioPlayer
  src="https://sveltejs.github.io/assets/music/strauss.mp3"
  title="The Blue Danube Waltz"
  composer="Johann Strauss"
  performer="European Archive"
/>

<!-- https://musopen.org/music/43775-the-planets-op-32/ -->
<AudioPlayer
  src="https://sveltejs.github.io/assets/music/holst.mp3"
  title="Mars, the Bringer of War"
  composer="Gustav Holst"
  performer="USAF Heritage of America Band"
/>

<!-- https://musopen.org/music/8010-3-gymnopedies/ -->
<AudioPlayer
  src="https://sveltejs.github.io/assets/music/satie.mp3"
  title="Gymnopédie no. 1"
  composer="Erik Satie"
  performer="Prodigal Procrastinator"
/>

<!-- https://musopen.org/music/2567-symphony-no-5-in-c-minor-op-67/ -->
<AudioPlayer
  src="https://sveltejs.github.io/assets/music/beethoven.mp3"
  title="Symphony no. 5 in Cm, Op. 67 - I. Allegro con brio"
  composer="Ludwig van Beethoven"
  performer="European Archive"
/>

<!-- https://musopen.org/music/43683-requiem-in-d-minor-k-626/ -->
<AudioPlayer
  src="https://sveltejs.github.io/assets/music/mozart.mp3"
  title="Requiem in D minor, K. 626 - III. Sequence - Lacrymosa"
  composer="Wolfgang Amadeus Mozart"
  performer="Markus Staab"
/>

Exports


Anything exported from a context="module" script block becomes an export from the module itself. If we export a stopAll function from AudioPlayer.svelte...

<script context="module">
  const elements = new Set();

  export function stopAll() {
    elements.forEach(element => {
      element.pause();
    });
  }
</script>

...we can then import it from App.svelte...

<script>
  import AudioPlayer, { stopAll } from './AudioPlayer.svelte';
</script>

...and use it in an event handler:

<button on:click={stopAll}>
stop all audio
</button>

You can't have a default export, because the component is the default export. For working example you can check here.

Debugging


Occasionally, it's useful to inspect a piece of data as it flows through your app.

One approach is to use console.log(...) inside your markup. If you want to pause execution, though, you can use the {@debug ...} tag with a comma-separated list of values you want to inspect:

{@debug user}

<h1>Hello {user.firstname}!</h1>

If you now open your devtools and start interacting with the <input> elements, you'll trigger the debugger as the value of user changes. For working example you can check here.



Indonesia


Sharing Code


Pada semua contoh yang sudah kita lihat sejauh ini, block <script> adalah tempat meletakkan program yang akan berjalan ketika masing-masing komponen sudah ter inisialisasi. Untuk kebanyakan komponen, itu sudah sesuai dengan kebutuhan kita.

Tapi terkadang, kita butuh menjalankan program di luar komponen itu sendiri. Sebagai contoh, kita bisa menjalankan 5 player pada contoh berikut bersamaan; tetapi akan lebih baik, jika kita menjalankan satu maka yang lain otomatis akan berhenti.

Kita bisa melakukan itu dengan mendeklarasikan blok <script context="module">. Program yang terdapat di dalamnya hanya akan berjalan sekali ketika modul pertama dijalankan, dan bukan ketika setiap komponen terbentuk. Letakkan di bagian atas AudioPlayer.svelte:

<script context="module">
  let current;
</script>

<script>
  export let src;
  export let title;
  export let composer;
  export let performer;

  let audio;
  let paused = true;

  function stopOthers() {
    if (current && current !== audio) current.pause();
    current = audio;
  }
</script>

<style>
  article { margin: 0 0 1em 0; max-width: 800px }
  h2, p { margin: 0 0 0.3em 0; }
  audio { width: 100%; margin: 0.5em 0 1em 0; }
  .playing { color: #ff3e00; }
</style>

<article class:playing={!paused}>
  <h2>{title}</h2>
  <p><strong>{composer}</strong> / performed by {performer}</p>

  <audio
    bind:this={audio}
    bind:paused
    on:play={stopOthers}
    controls
    {src}
  ></audio>
</article>

Sekarang sudah memungkinkan untuk setiap komponen saling ber'bicara' tanpa perlu menggunakan manajemen state lagi, kita hanya perlu membuat <AudioPlayer> di App.svelte dan ini akan memberikan properti yang kita butuhkan, yaitu variabel current sekarang sudah bisa digunakan pada semua <AudioPlayer>:

<script>
  import AudioPlayer from './AudioPlayer.svelte';
</script>

<!-- https://musopen.org/music/9862-the-blue-danube-op-314/ -->
<AudioPlayer
  src="https://sveltejs.github.io/assets/music/strauss.mp3"
  title="The Blue Danube Waltz"
  composer="Johann Strauss"
  performer="European Archive"
/>

<!-- https://musopen.org/music/43775-the-planets-op-32/ -->
<AudioPlayer
  src="https://sveltejs.github.io/assets/music/holst.mp3"
  title="Mars, the Bringer of War"
  composer="Gustav Holst"
  performer="USAF Heritage of America Band"
/>

<!-- https://musopen.org/music/8010-3-gymnopedies/ -->
<AudioPlayer
  src="https://sveltejs.github.io/assets/music/satie.mp3"
  title="Gymnopédie no. 1"
  composer="Erik Satie"
  performer="Prodigal Procrastinator"
/>

<!-- https://musopen.org/music/2567-symphony-no-5-in-c-minor-op-67/ -->
<AudioPlayer
  src="https://sveltejs.github.io/assets/music/beethoven.mp3"
  title="Symphony no. 5 in Cm, Op. 67 - I. Allegro con brio"
  composer="Ludwig van Beethoven"
  performer="European Archive"
/>

<!-- https://musopen.org/music/43683-requiem-in-d-minor-k-626/ -->
<AudioPlayer
  src="https://sveltejs.github.io/assets/music/mozart.mp3"
  title="Requiem in D minor, K. 626 - III. Sequence - Lacrymosa"
  composer="Wolfgang Amadeus Mozart"
  performer="Markus Staab"
/>

Exports


Apapun yang di export dari blok skrip context="module" akan menjadi export dari modul itu sendiri. Jika kita mengekspor fungsi stopAll dari AudioPlayer.svelte...

<script context="module">
  const elements = new Set();

  export function stopAll() {
    elements.forEach(element => {
      element.pause();
    });
  }
</script>

...kita bisa meng impor dari App.svelte...

<script>
  import AudioPlayer, { stopAll } from './AudioPlayer.svelte';
</script>

...dan menggunakannya pada handler even:

<button on:click={stopAll}>
stop all audio
</button>

Kita tidak bisa mempunyai ekspor default, karena komponen itu sendiri sudah merupakan default ekspor. Contoh lengkap bisa dilihat di sini.

Debugging


Terkadang, kita perlu mengecek data yang berjalan di dalam app kita.

Salah satu cara adalah dengan menggunakan console.log(...) dalam program. Akan tetapi jika kita ingin mem pause eksekusi program, kita bisa menggunakan tag {@debug ...} dengan mencantumkan nilai-nilai yang ingin kita cek, dipisahkan oleh tanda koma:

{@debug user}

<h1>Hello {user.firstname}!</h1>

Jika sekarang kita membuka devtools dan mulai berinteraksi dengan elemen <input>, maka debugger akan berjalan setiap nilai dari user berubah. Contoh lengkap bisa dilihat di sini.


No comments :

Post a Comment

THINK: is it True? is it Helpful? is it Inspiring? is it Necessary? is it Kind?