# 指令解析

`RJS` 的 `#SET_DOM` 走訪模板時套用指令的順序，以及每個指令（`:path`、`:for`、`:if`、`:model`、`:[attr]`、`@[event]`）的行為。

## 指令解析順序

`#SET_DOM` 依序走訪每個子元素並套用指令。帶有 `:path` 或 `:for` 標籤的節點會短路進入各自的處理函式，並跳過該節點後續的流程：

```mermaid
graph TB
    Node["子元素"] --> PathCheck{"有 :path 屬性?"}
    PathCheck -->|是| SetPath["#setPath: 抓取片段並內嵌，返回"]
    PathCheck -->|否| ForCheck{"有 :for 屬性?"}
    ForCheck -->|是| FitFor["#FIT_FOR: 展開迴圈，返回"]
    ForCheck -->|否| SetIf["#setIf: :if / :else-if / :else"]
    SetIf --> FitModel["#FIT_MODEL: 表單雙向綁定"]
    FitModel --> FitAttr["#FIT_ATTRIBUTE: :[attr] / :[css]"]
    FitAttr --> FitEvent["#FIT_EVENT: @[event]"]
    FitEvent --> FitText["#FIT_TEXT: {{ }} 文字插值"]
    FitText --> Recurse["#SET_DOM(child) — 遞迴至孫節點"]
```

尚未由 `#setIf` 判定完成（後方仍有待解析的 `:else-if`／`:el-if`／`:else` 兄弟節點）的元素會在這一輪被跳過；`#setIf` 移除落敗分支後，會對父節點重新呼叫一次 `#SET_DOM`。


## 各指令行為

### `:path` — 非同步片段載入

僅套用於帶 `:path` 屬性的元素。`#setPath` 會 `fetch` 目標 URL，將回傳的 HTML 作為子節點插入，並對該片段重新執行 `#SET_DOM`（除非片段內含 `new PD` 建構式，此時不處理）。片段中的 `script` 標籤會被移至 `document.body` 底部執行；其餘內容原地展開，原本的佔位節點會被移除。fetch 失敗時同樣會移除該節點。

### `:for` — 迴圈展開

支援三種格式：`item in items`、`(item, index) in items`、`(key, value) in object`。`#FIT_FOR` 針對每個陣列項目（或物件鍵）複製一份模板節點，綁定 `subItem = { [val0]: item, [val1]: index }`（或 `{ [val0]: key, [val1]: value }`），對每份複本渲染屬性／事件／文字後，將整批節點插回原節點所在位置。巢狀物件項目會進行完整的遞迴 `#SET_DOM`；純值項目則只做屬性／事件／文字代換。

### `:if` / `:else-if` / `:el-if` / `:else`

`#setIf` 會將 `:if` 節點與其後緊接的 `:else-if`／`:el-if`／`:else` 兄弟節點收集為一組，依序評估各條件，僅保留第一個符合的節點（同組內即使後方節點自身條件成立，也一律移除）。支援的運算子：`>`、`<`、`>=`／`>==`、`<=`／`<==`、`==`／`===`、`!=`／`!==`。`==`／`!=` 會先特判 `null`、`true`、`false`、`empty`（空字串檢查）等字面值，其餘才回退為字串相等比較。

### `:model` — 表單雙向綁定

`#FIT_MODEL` 依綁定元素型別分派：checkbox／radio 監聽 `change`，並將所有勾選值以 `,` 串接；`select` 監聽 `change`；純 `input`／`textarea` 同時監聽 `keyup` 與 `change`。無論哪種情況，handler 都是直接寫入該次渲染傳入的 `data` 物件——寫入本身不會觸發任何 observer 或響應式重新渲染。

### `:[attr]` / `:[css]` — 屬性與樣式綁定

`#FIT_ATTRIBUTE` 收集所有符合 `/^:[\w\-]+$/`（排除上述指令名稱）的屬性，透過 `#GET_VALUE` 解析其值後交給 `#SET_ATTRIBUTE`。`:class` 會呼叫 `_class()`（見 [Element 擴充](/zh/api-reference-element)）；`:id`／`:src`／`:alt`／`:href`／`:html` 直接對應到相同名稱的 DOM 屬性；其餘 camel-case 後存在於 `element.style` 上的鍵視為 CSS 屬性；其餘一律作為純 HTML attribute（若解析值為空則移除）。

### `@[event]` — 事件綁定

`#FIT_EVENT` 比對 `/^@[\w]+$/` 格式的屬性，將 `@click` 改寫為 `onclick`，並在 `this.event` 中查找對應的 handler 名稱。在 `:for` 迴圈內，handler 名稱本身也可以是逐項資料值（透過與 `{{ }}` 插值相同的 key-path 解析），而非固定方法名。
