each
邏輯區塊(三)差不多在這個時候,一位滿懷抱負的年輕記者在某天早晨來到 Svelte 家門口,採訪他是否有什麼項目要擺在陣列裡頭。
「關於哪個陣列要擺放哪些項目?」Svelte 先生禮貌的反問。~節錄自《The Great Svelte:第六章》
{:else}
處理空陣列情形 昨天我們用 each
邏輯搭配加減按鈕的事件設定,成功做出隨著使用者喜好改變色票數量的色票產生器了。同時我們把色票的數量限制在 1
到 6
之間,若是使用者利用計數器改變色票數量超過我們允許的範圍時,互動視窗就會跳出來提醒使用者。用這個做法就可以避免當色票數量變成 0
時,畫面上空空如也的情況,如圖一。
圖一、空空的色票數量 0
這樣子做好像也不差?不過我們今天要來介紹的是,如何特別處理陣列數量為 0
的情形。
{:else}
處理空陣列情形 因為 each
段落是從陣列出發,藉由迭代陣列內的項目去一一產生 HTML 的元素,當然很有可能碰到陣列為空陣列的情況。所以 Svelte 也特別提供方法來處理空陣列的情形:
{#each array as item}
<p>{item}<p>
{:else}
<p>No item in the array.</p>
{/each}
第一行:{#each array as item}
用 {#each}
開始 each
段落的迭代。
第二行:<p>{item}<p>
若 array
這個陣列當中有項目,就一一顯示項目內容。
第三行:{:else}
選擇性的搭配一個 {:else}
邏輯段落,用來處理 array
為空陣列的情形。
第四行:<p>No item in the array.</p>
若陣列為空陣列,則顯示 {:else}
段落內的內容。
第五行:{/each}
用 {/each}
結束整個 each
邏輯段落。
當迭代的陣列變成空陣列時,這個新增加的 {:else}
段落就會站出來補上空缺。語法的概念很像是:如果陣列當中有項目,就用 {#each}
去迭代陣列產生 HTML 元素。如果陣列當中沒有項目了,就用 {:else}
去產生 HTML 元素。最後用 {/each}
結束這個邏輯段落。
雖然我們目前只先學到了 each
這個邏輯段落,不過大家可以先留意一下,在 Svelte 提供的邏輯段落裡,會常常使用這樣子的語法設計:用 {#}
展開邏輯段落,用 {:}
延續邏輯段落,用 {/}
結束邏輯段落。
按照慣例,我們介紹了新的一個語法,今天也試著應用在我們的專案上面吧。為了能讓空陣列能夠發生,也就是我們的 palettes
這個陣列需要能被清零,首先要到 App.svelte
修改 tobeCount
允許的範圍:
/src/App.svelte
<script>
import Counter from "./lib/Counter.svelte";
import Modal from "./lib/Modal.svelte";
import Palettes from "./lib/Palettes.svelte";
let showModal = false;
let palettes = [
{ hex: "ff4000", locked: false, id: "init_01" },
{ hex: "32e6e3", locked: false, id: "init_02" },
{ hex: "009fe9", locked: false, id: "init_03" },
];
$: count = palettes.length;
const generateTone = () =>
("0" + Math.round(255 * Math.random()).toString(16)).slice(-2);
const generateHex = () =>
[generateTone(), generateTone(), generateTone()].reduce(
(a, c) => a + c,
""
);
const generatePalette = (() => {
let uuid = 0;
return () => ({
hex: generateHex(),
locked: false,
id: `${uuid++}`,
});
})();
let someState = "TheGreatSvelte";
const sparkle = (text) => {
const sparkles = ["★", "☆", "✧", "✪"];
const randomSparkles = () =>
sparkles[Math.floor(Math.random() * sparkles.length)];
const sparkledText = text
.split("")
.reduce((a, c) => a + randomSparkles() + c, "");
return sparkledText;
};
const href = "https://ithelp.ithome.com.tw/users/20120178/ironman/7031";
const handleClick = (e) => {
console.log(e);
const tobeCount = count + e.detail;
if (0 <= tobeCount && tobeCount < 7) {
switch (e.detail) {
case 1:
palettes = [...palettes, generatePalette()];
break;
case -1:
palettes = palettes.slice(0, -1);
break;
}
} else showModal = true;
};
</script>
第四十六行:const handleClick = (e) => {
落落長一串程式碼,只需要修改 handleClick
當中的邏輯。
第四十九行:if (0 <= tobeCount && tobeCount < 7) {
讓 tobeCount
允許為 0
,這樣我們才有機會把 palettes
陣列當中的所有項目清空,展現出 {:else}
的功能。
修改好 App.svelte
之後,先來試試看如果沒有加上 {:else}
會發生什麼事。當我們從計數器不斷移除色票之後,最後色票欄就變得像圖一空空如也的樣子,什麼都沒有顯示了。
圖一、空空如也的狀態
如果不喜歡這樣的效果,讓我們練習練習今天學會的語法,試著加上 {:else}
來處理空陣列的狀況吧:
/src/lib/Palettes.svelte
<script>
import unlock from "../assets/unlock.svg";
export let palettes;
</script>
<div class="palettes">
{#each palettes as { hex, id } (id)}
<div class="card">
<div class="palette" style="background: #{hex}" />
<div class="hex-code">
<p>
{hex}
</p>
</div>
<div class="lock-icon">
<img src={unlock} alt="color-unlocked" />
</div>
</div>
{:else}
<div class="card no-color">
<div>
<p>No color to show. Please add a color.</p>
</div>
</div>
{/each}
</div>
第十九行:{:else}
在 {#each}
之後加上 {:else}
,表示我們想要用以下的邏輯段落來處理 palettes
為空陣列的情況。
第二十行:<div class="card no-color">
放入一個 HTML 的 <div>
,並加上 card
跟 no-color
這兩個 class 來修飾這個 <div>
。
第二十五行:{/each}
不需要做修改,只是提醒大家記得要用 {/each}
來結束整個 each
邏輯段落。
圖二、請新增一個顏色
太棒了,我們學會如何在 each
邏輯段落中用 {:else}
來處理空陣列囉!完整的程式碼可以在 Github 資源庫上面找到。好的,那麼今天的文章內容就到這邊了,謝謝大家。