<!-- [코드 8-1-1] App.svelte-->
<script>
let promise = Promise.resolve('initialized');
function runPromise(wantReject) {
// wantReject -- false : 리졸브 , true : 리젝
return new Promise((resolve, reject) => {
if (wantReject) {
reject(new Error('rejcted'));
} else {
resolve('resolved');
}
})
}
</script>
<button on:click={ ()=>{promise = runPromise(false);} }>resolve</button>
<button on:click={ ()=>{promise = runPromise(true);} }>reject</button>
{#await promise}
Pending
{:then res}
Fulfilled :
<p>{res}</p>
{:catch err}
Rejected :
<p>{err}</p>
{/await}
#await - :then - :catch - /await
패턴으로 await블록을 사용할 수 있다. 초기상태 또는 Fulfilled상태일 때 then블록이 실행된다. rejected상태일 때 catch블록이 실행된다. pending상태일 때 가장 윗 블록이 실행된다.
<!-- [코드 8-1-2] App.svelte-->
<script> ... </script>
<button ...> ... </button>
{#await promise then res}
Fulfilled :
<p>{res}</p>
{/await}
만약 pending, rejected상태를 처리할 필요가 없다면 위와 같이 축약형으로서 then부분(Fulfilled상태)만 처리할 수 있다.
<!-- [코드 8-2-1] App.svelte-->
<script>
let arr = [
{ name:'a', value:1, },
{ name:'b', value:10, },
{ name:'c', value:100, },
];
</script>
<section>
{#each arr as el}
<button on:click={ ()=>{el.value++;} }>{el.name} {el.value}</button>
{/each}
</section>
위 코드에서 button의 인라인 핸들러는 대입문이 없으므로 반응성을 갖지 않을 것으로 예상된다. 그러나 반복문 내 요소에 대해 인라인핸들러로 값을 변경하면, 번들된 코드에서는 반응성을 갖도록 처리한다.
<!-- [코드 8-3-1] App.svelte-->
<script>
let arr = [
{ name:'a', value:1, },
{ name:'b', value:10, },
{ name:'c', value:100, },
];
let marginTop = 0;
</script>
<section style="--marginTop : {marginTop}">
{marginTop}
{#each arr as el}
<button
on:click={ ()=>{el.value++;} }
on:click={ ()=>{marginTop+=10;} }>
{el.name} {el.value}
</button>
{/each}
</section>
<style>
section {
margin-top : calc( var(--marginTop) * 1px );
}
button {
margin : 4px;
}
</style>
같은 핸들러를 여러개 등록할 수도 있다. 위 예제는 2개의 on:click핸들러가 걸려있고, 클릭하면 el.value를 1증감함과 동시에 margin-top을 10 증감한다.
<script>
function showThis(e) {
console.log('[target] : ', e.target);
console.log('[currentTarget] :', e.currentTarget);
}
</script>
아래 8-4-X 모든 코드에는 위 코드가 포함되어있다고 가정한다.
<!-- [코드 8-4-1] App.svelte-->
<a href="https://github.com/wonjinYi"
target="_blank"
on:click|preventDefault={e=>showThis(e)}>
click
</a>
on:__|preventDefault
와 같이 작성하여 기본동작을 방지한다. (e.preventDefault()
와 동일. )
<!-- [코드 8-4-2] App.svelte-->
<button on:click|once={e=>showThis(e)}>
click
</button>
on:__|once
와 같이 작성하여 해당 핸들러가 최초 1회만 동작하도록 한다.
<!-- [코드 8-4-3] App.svelte-->
<div on:click={showThis}>
<button on:click|stopPropagation={showThis}>click</button>
</div>
on:__|stopPropagation
과 같이 작성하여 해당 핸들러에 대하여 이벤트버블링을 방지한다. ( e.stopPropagation()
과 동일 )
<!-- [코드 8-4-4] App.svelte-->
<div on:click|capture={showThis}>
<button on:click={showThis}>click</button>
</div>
on:__|capture
와 같이 작성하여 {capture:true}
옵션을 부여한다.
<!-- [코드 8-4-5] App.svelte-->
<div on:click|self={showThis}>
<button>click</button>
</div>
on:__|self
와 같이 작성하여 e.target, e.currentTarget이 동일할 때에만 이벤트 핸들러를 실행하도록 할 수 있다.
<!-- [코드 8-4-6] App.svelte-->
<div class="outer" on:wheel|passive={showThis}>
<div class="inner"></div>
</div>
<style>
.outer {
width : 200px;
height : 500px;
background-color : yellow;
overflow:auto;
}
.inner{
width : 100px;
height : 5000px;
background-color: green;
}
</style>
on:__:passive
와 같이 작성하여 {passive:true}
옵션을 부여한다.