커스텀 Turbo Stream 액션의 구현
초기에는 특정 목적(예: 폭죽 애니메이션)을 위한 커스텀 Turbo Stream 액션을 구현했습니다.
* 컨트롤러 로직: Rails 컨트롤러는 오직 비즈니스 로직에만 집중하며, 특정 조건(예: 정답)이 충족될 경우 turbo_stream.action(:confetti)
를 렌더링합니다.
ruby
class QuizController < ApplicationController
def create
if correct_answer?
render turbo_stream: turbo_stream.action(:confetti)
else
# Handle incorrect answer
end
end
end
* JavaScript 확장: Turbo.StreamActions 객체에 confetti
함수를 추가하여 해당 액션이 호출될 때 특정 JavaScript 함수(launchConfetti()
)를 실행하도록 정의합니다.
javascript
Turbo.StreamActions.confetti = function () {
launchConfetti();
};
일반화된 ‘trigger’ 액션으로의 발전
다양한 프론트엔드 기능(스피너 숨기기, 다이얼로그 닫기, 사운드 재생 등)에 대한 조율이 필요해지면서, 개별적인 커스텀 액션 대신 범용적인 trigger
액션의 필요성이 대두되었습니다.
* 범용 trigger
액션: 컨트롤러는 turbo_stream.action(:trigger, "이벤트-이름")
형태로 특정 이벤트를 발생시키도록 지시합니다. 여기서 두 번째 인자는 발생시킬 커스텀 이벤트의 이름이 됩니다.
ruby
class QuizController < ApplicationController
def create
if correct_answer?
render turbo_stream: turbo_stream.action(:trigger, "launch-confetti")
else
# ...
end
end
end
* 이벤트 디스패치: Turbo.StreamActions.trigger
함수는 Turbo Stream 응답을 받아 this.target
에 명시된 이름으로 DOM 이벤트를 발생시킵니다.
javascript
Turbo.StreamActions.trigger = function () {
document.dispatchEvent(new Event(this.target));
};
프론트엔드 컴포넌트의 이벤트 리스너 활용
trigger
액션을 통해 발생한 커스텀 DOM 이벤트는 프론트엔드 컴포넌트가 독립적으로 반응할 수 있는 기반을 제공합니다.
* Stimulus 컨트롤러: Stimulus 컨트롤러와 같은 프론트엔드 컴포넌트는 document.addEventListener
를 사용하여 특정 이벤트를 수신하고, 해당 이벤트 발생 시 정의된 콜백 함수를 실행합니다.
```javascript
export default class extends Controller {
connect() {
document.addEventListener(“launch-confetti”, this.launchConfetti);
}
launchConfetti() {
// 폭죽 애니메이션 로직
}
}
``` * **다양한 활용 사례**: 이 패턴은 다음과 같은 다양한 시나리오에 적용될 수 있습니다.
* `hide-loading-spinner`: 데이터 로드 성공 후 로딩 스피너 숨기기
* `play-notification-sound`: 중요한 알림에 대한 사운드 재생
* `update-progress-bar`: 장시간 실행되는 프로세스 중 진행률 바 업데이트
* `trigger-analytics-event`: 사용자 행동 추적을 위한 분석 이벤트 발생