μ¬λλ€μ΄ htmxλ₯Ό μ²μ μ¬μ©ν λ μμ£Ό 묻λ μ§λ¬Έ μ€ νλλ λ€μκ³Ό κ°μ΅λλ€:
βνλ©΄μ λ€λ₯Έ μ½ν μΈ λ₯Ό μ λ°μ΄νΈν΄μΌ ν©λλ€. μ΄λ»κ² ν΄μΌ νλμ?β
μ΄ μμ μ μνν μ μλ μ¬λ¬ κ°μ§ λ°©λ²μ΄ μμΌλ©°, μ΄ μμ μμλ λͺ κ°μ§ λ°©λ²μ μλ΄ν΄ λλ¦¬κ² μ΅λλ€.
μλμ κΈ°λ³Έ UIλ₯Ό μ¬μ©νμ¬ μ΄ κ°λ μ μ€λͺ νκ² μ΅λλ€: κ°λ¨ν μ°λ½μ² ν μ΄λΈκ³Ό, μ΄ ν μ΄λΈμ μλ‘μ΄ μ°λ½μ²λ₯Ό μΆκ°νκΈ° μν΄ hx-postμ μ¬μ©νλ νΌμ λλ€.
<h2>Contacts</h2>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody id="contacts-table">
...
</tbody>
</table>
<h2>Add A Contact</h2>
<form hx-post="/contacts">
<label>
Name
<input name="name" type="text">
</label>
<label>
Email
<input name="email" type="email">
</label>
</form>
μ¬κΈ°μ λ¬Έμ λ, νΌμμ μλ‘μ΄ μ°λ½μ²λ₯Ό μ μΆν λ, μ°λ½μ² ν μ΄λΈμ΄ μλ‘ κ³ μΉ¨λμ΄ λ°©κΈ νΌμμ μΆκ°λ μ°λ½μ²λ₯Ό ν¬ν¨νλλ‘ ν΄μΌ νλ€λ κ²μ λλ€.
μ΄λ€ ν΄κ²°μ± μ΄ μμκΉμ?
μ¬κΈ°μ κ°μ₯ κ°λ¨ν ν΄κ²°μ±
μ νΌμ νκ²μ ν
μ΄λΈκ³Ό νΌμ λͺ¨λ ν¬ν¨νλλ‘ βνμ₯βνλ κ²μ
λλ€. μλ₯Ό λ€μ΄, μ 체λ₯Ό div
λ‘ κ°μΈκ³ νΌμμ ν΄λΉ div
λ₯Ό νκ²μΌλ‘ μ€μ ν μ μμ΅λλ€:
<div id="table-and-form">
<h2>Contacts</h2>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody id="contacts-table">
...
</tbody>
</table>
<h2>Add A Contact</h2>
<form hx-post="/contacts" hx-target="#table-and-form">
<label>
Name
<input name="name" type="text">
</label>
<label>
Email
<input name="email" type="email">
</label>
</form>
</div>
μ¬κΈ°μ μ°λ¦¬λ hx-target μμ±μ μ¬μ©νμ¬ ν¬ν¨νλ div
λ₯Ό νκ²μΌλ‘ μ§μ νκ³ μμ΅λλ€.
/contacts
μ λν POST
μλ΅μμ ν
μ΄λΈκ³Ό νΌμ λͺ¨λ λ λλ§ν΄μΌ ν©λλ€.
μ΄ λ°©λ²μ κ°λ¨νκ³ μ λ’°ν μ μμ§λ§, νΉλ³ν μ°μνλ€κ³ λκ»΄μ§μ§λ μμ μ μμ΅λλ€.
μ΄ λ¬Έμ λ₯Ό ν΄κ²°νλ λ μ κ΅ν μ κ·Ό λ°©μμ Out of Band μ€μμ μ¬μ©νμ¬ DOMμ μ λ°μ΄νΈλ μ½ν μΈ λ₯Ό μ½μ νλ κ²μ λλ€.
μ΄ λ°©λ²μ μ¬μ©νλ©΄ HTMLμ μ²μ μ€μ ν κ·Έλλ‘ μ μ§λ μ μμ΅λλ€:
<h2>Contacts</h2>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody id="contacts-table">
...
</tbody>
</table>
<h2>Add A Contact</h2>
<form hx-post="/contacts">
<label>
Name
<input name="name" type="text">
</label>
<label>
Email
<input name="email" type="email">
</label>
</form>
νλ‘ νΈ μλμμ 무μΈκ°λ₯Ό μμ νλ λμ , /contacts
μ λν POST
μλ΅μμ μΆκ°μ μΈ μ½ν
μΈ λ₯Ό ν¬ν¨ν μ μμ΅λλ€:
<tbody hx-swap-oob="beforeend:#contacts-table">
<tr>
<td>Joe Smith</td>
<td>joe@smith.com</td>
</tr>
</tbody>
<label>
Name
<input name="name" type="text">
</label>
<label>
Email
<input name="email" type="email">
</label>
μ΄ μ½ν
μΈ λ hx-swap-oob μμ±μ μ¬μ©νμ¬ #contacts-table
μ μμ μ μΆκ°νμ¬ μ°λ½μ²κ° μ±κ³΅μ μΌλ‘ μΆκ°λ ν ν
μ΄λΈμ μ
λ°μ΄νΈν©λλ€.
λ μ κ΅ν μ κ·Ό λ°©μμ μ±κ³΅μ μΌλ‘ μ°λ½μ²κ° μμ±λμμ λ ν΄λΌμ΄μΈνΈ μΈ‘ μ΄λ²€νΈλ₯Ό νΈλ¦¬κ±°νκ³ , κ·Έ μ΄λ²€νΈλ₯Ό ν μ΄λΈμμ κ°μ§νμ¬ ν μ΄λΈμ μλ‘κ³ μΉ¨νλ κ²μ λλ€.
<h2>Contacts</h2>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody id="contacts-table" hx-get="/contacts/table" hx-trigger="newContact from:body">
...
</tbody>
</table>
<h2>Add A Contact</h2>
<form hx-post="/contacts">
<label>
Name
<input name="name" type="text">
</label>
<label>
Email
<input name="email" type="email">
</label>
</form>
μ¬κΈ°μλ μ°λ½μ² ν
μ΄λΈμ λ€μ λ λλ§νλ /contacts/table
μ΄λΌλ μλ‘μ΄ μλν¬μΈνΈλ₯Ό μΆκ°νμ΅λλ€.
μ΄ μμ²μ νΈλ¦¬κ±°λ newContact
μ΄λΌλ μ¬μ©μ μ μ μ΄λ²€νΈμ
λλ€. μ΄ μ΄λ²€νΈλ νΌμ μλ΅μ μν΄ νΈλ¦¬κ±°λ λ μ΄λ²€νΈ λ²λΈλ§μΌλ‘ μΈν΄ body
μ λλ¬νκ² λλ―λ‘, μ΄λ₯Ό body
μμ κ°μ§ν©λλ€.
/contacts
λ‘μ POST
μμ²μ΄ μ±κ³΅μ μΌλ‘ μλ£λμ΄ μ°λ½μ²κ° μμ±λλ©΄, μλ΅μλ λ€μκ³Ό κ°μ HX-Trigger μλ΅ ν€λκ° ν¬ν¨λ©λλ€:
HX-Trigger:newContact
μ΄ ν€λλ ν
μ΄λΈμ΄ /contacts/table
λ‘ GET
μμ²μ 보λ΄λλ‘ νΈλ¦¬κ±°νλ©°, μ΄λ₯Ό ν΅ν΄ μλ‘ μΆκ°λ μ°λ½μ² ν(λ° ν
μ΄λΈμ λλ¨Έμ§ λΆλΆ)μ΄ λ λλ§λ©λλ€.
μμ£Ό κΉλν μ΄λ²€νΈ κΈ°λ° νλ‘κ·Έλλ° λ°©μμ λλ€!
λ§μ§λ§ μ κ·Ό λ°©μμ REST-ful κ²½λ‘ μμ‘΄μ±μ μ¬μ©νμ¬ ν μ΄λΈμ μλ‘κ³ μΉ¨νλ κ²μ λλ€. htmxμ μ μ μΈ Intercooler.jsλ κ²½λ‘ κΈ°λ° μμ‘΄μ±μ λΌμ΄λΈλ¬λ¦¬μ ν΅ν©νμ΅λλ€.
htmxλ μ΄ κΈ°λ₯μ κΈ°λ³Έ κΈ°λ₯μμ μ μΈνμ§λ§, path depsλΌλ νμ₯μ ν΅ν΄ λΉμ·ν κΈ°λ₯μ μ 곡ν©λλ€.
νμ₯μ μ¬μ©νλλ‘ μμ λ₯Ό μ λ°μ΄νΈνλ €λ©΄, νμ₯ μλ°μ€ν¬λ¦½νΈλ₯Ό λ‘λν λ€μ λ€μκ³Ό κ°μ΄ HTMLμ μ£Όμ μ²λ¦¬ν΄μΌ ν©λλ€:
<h2>Contacts</h2>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Email</th>
<th></th>
</tr>
</thead>
<tbody id="contacts-table" hx-get="/contacts/table" hx-ext="path-deps" hx-trigger="path-deps" path-deps="/contacts">
...
</tbody>
</table>
<h2>Add A Contact</h2>
<form hx-post="/contacts">
<label>
Name
<input name="name" type="text">
</label>
<label>
Email
<input name="email" type="email">
</label>
</form>
μ΄μ νΌμ΄ /contacts
URLλ‘ POST
λ₯Ό ν λ, path-deps
νμ₯μ μ΄λ₯Ό κ°μ§νμ¬ μ°λ½μ² ν
μ΄λΈμ path-deps
μ΄λ²€νΈλ₯Ό νΈλ¦¬κ±°νμ¬ μμ²μ λ°μμν΅λλ€.
μ΄ μ κ·Ό λ°©μμ μ₯μ μ μλ΅ ν€λμ κ΄λ ¨λ 볡μ‘ν μ²λ¦¬λ₯Ό νΌν μ μλ€λ μ μ
λλ€. λ¨μ μ μ°λ½μ²κ° μ±κ³΅μ μΌλ‘ μμ±λμ§ μμλλΌλ λͺ¨λ POST
μμ²μμ μμ²μ΄ λ°μνλ€λ κ²μ
λλ€.
μΌλ°μ μΌλ‘λ νκ²μ νμ₯νλ 첫 λ²μ§Έ μ κ·Ό λ°©μμ κΆμ₯ν©λλ€. νΉν μ λ°μ΄νΈν΄μΌ νλ μμλ€μ΄ DOMμμ μλ‘ κ°κΉμ΄ μλ κ²½μ°μλ λμ± κ·Έλ μ΅λλ€. μ΄ λ°©λ²μ κ°λ¨νκ³ μ λ’°ν μ μμ΅λλ€.
κ·Έ λ€μμΌλ‘λ μ¬μ©μ μ μ μ΄λ²€νΈμ OOB μ€μ μ κ·Ό λ°©μ μ€ νλλ₯Ό μ νν μ μμ΅λλ€. μ λ μ΄λ²€νΈ μ§ν₯ μμ€ν μ μ νΈνκΈ° λλ¬Έμ μ¬μ©μ μ μ μ΄λ²€νΈ μ κ·Ό λ°©μμ μ νΈνμ§λ§, μ΄λ κ°μΈμ μΈ μ·¨ν₯μ λλ€. μ΄λ κ²μ μ νν μ§λ λ³ΈμΈμ μννΈμ¨μ΄ μμ§λμ΄λ§ μ·¨ν₯κ³Ό μλ² μΈ‘ κΈ°μ κ³Όμ μ ν©μ±μ λ°λΌ κ²°μ ν΄μΌ ν©λλ€.
λ§μ§λ§μΌλ‘, path-deps μ κ·Ό λ°©μμ ν₯λ―Έλ‘μ΄ μ κ·Ό λ°©μμΌλ‘, λ§μ½ μ΄ κ°λ μ΄ λ³ΈμΈμ μ μ μ λͺ¨λΈκ³Ό μ 체 μμ€ν μν€ν μ²μ μ λ§λλ€λ©΄, λͺ μμ μΈ μλ‘κ³ μΉ¨μ νΌνλ μ¬λ―Έμλ λ°©λ²μ΄ λ μ μμ΅λλ€. νμ§λ§ μ΄ κ°λ μ΄ ν¬κ² λλ¦¬μ§ μλλ€λ©΄, μ΄ μ κ·Ό λ°©μμ λ§μ§λ§μΌλ‘ κ³ λ €ν΄λ³΄μκΈΈ κΆμ₯ν©λλ€.