터보 프레임 모달 구현을 위한 두 가지 핵심 요구사항
터보 프레임 모달을 효과적으로 구현하기 위해서는 다음 두 가지 주요 조건을 충족해야 합니다.
* 링크 타겟팅: 모달로 렌더링하려는 액션으로 연결되는 링크는 data: { turbo_frame: 'modal' }
속성을 사용하여 ‘modal’이라는 특정 터보 프레임을 대상으로 지정해야 합니다. 이는 해당 링크 클릭 시 응답이 전체 페이지 대신 지정된 ‘modal’ 프레임 내에서 처리되도록 합니다.
ruby
<%= link_to 'New Task', new_task_path, class: 'btn', data: { turbo_frame: 'modal' } %>
* 컨트롤러 액션 레이아웃 지정: 모달로 의도된 컨트롤러 액션(예: new
, create
실패 시)은 render layout: 'modal'
을 통해 ‘modal’ 레이아웃을 명시적으로 지정해야 합니다. 이 레이아웃은 모달 콘텐츠를 감싸는 최소한의 구조를 제공하며, 일반적으로 비어있는 turbo-frame
요소를 포함하여 모달이 렌더링될 위치를 정의합니다.
```ruby
class TasksController < ApplicationController
def new
@task = Task.new
render layout: ‘modal’
end
def create
@task = Task.new(task_params)
if @task.save
redirect_to tasks_path, notice: 'Task was successfully created.'
else
render :new, status: :unprocessable_content, layout: 'modal'
end
end
end
```
터보 프레임에서 벗어나기 (폼 제출 처리)
폼 제출 성공 시 모달 프레임에서 벗어나 일반 페이지로 리다이렉션하고, 실패 시에는 에러와 함께 모달 내에서 다시 렌더링하는 방법은 다음과 같습니다.
* turbo:frame-missing
이벤트 활용: 폼 제출 성공 시 Turbo는 기본적으로 레이아웃을 비워버리기 때문에, 애플리케이션 레이아웃에 있는 빈 ‘modal’ 터보 프레임이 “missing” 상태가 됩니다. 이 때 turbo:frame-missing
이벤트를 감지하여 프론트엔드에서 처리합니다.
javascript
document.addEventListener('turbo:frame-missing', (event) => {
if (event.target.id === 'modal') {
event.preventDefault()
event.detail.visit(event.detail.response.url, { action: 'replace' })
}
})
이 이벤트 핸들러는 성공적인 리다이렉트 응답을 Turbo Drive의 visit
함수를 통해 처리하여, 전체 페이지를 새로고침하거나 지정된 action: 'replace'
를 통해 “새로고침”처럼 작동하게 하여 모핑 및 스크롤 유지를 가능하게 합니다.
* 실패 시 모달 유지: 폼 제출 실패 시에는 컨트롤러에서 render :new, status: :unprocessable_content, layout: 'modal'
과 같이 ‘modal’ 레이아웃을 다시 지정하여 에러 메시지와 함께 폼을 모달 내에서 재렌더링합니다.