StimulusReflex를 사용하는 레일의 지연 로드 양식 필드

이 패턴은 외부 API를 호출하거나 느린 관계를 로드할 때 유용할 수 있는 Rails을 사용하여 StimulusReflex의 양식 필드를 지연 로드하는 데 도움이 될 수 있습니다.



예를 들어 사용자가 자신의 프로필에 표시할 수 있도록 사용자의 GitHub 리포지토리 목록을 가져오려는 양식이 있다고 가정해 보겠습니다.

GitHub의 API에서 이 데이터를 로드하는 데는 사용자가 보유한 리포지토리 수에 따라 몇 초가 걸릴 수 있으므로 전체 양식 로드를 지연하는 대신 비동기식으로 로드할 수 있습니다.

이니셜/app/views/users/_form.html.erb은 다음과 같습니다.

<%= form_with(model: user, url: [user], local: true) do |form| -%>
<div class="card">
  <ul class="list-group list-group-flush">
    <li class="list-group-item">
      <%= form.text_field :name, label: "Name", placeholder: "Enter name", required: true %>
    </li>
    <li class="list-group-item">
      <%= form.email_field :email, label: "Email", placeholder: "Enter email", required: true %>
    </li>
  </ul>
  <div class="card-footer">
    <%= form.submit "Save", class: "btn btn-secondary float-right" %>
  </div>
</div>
<% end %>


이제 우리의 Stimulus controller 을 첨부하는 로드 메시지가 있는 레이블과 div만 양식에 저장소에 대한 다른 섹션을 추가합니다.

<li class="list-group-item" data-reflex-root="#repositories">
  <label class="required">Repositories</label>
  <div id="repositories" data-controller="repositories">
    <i>Loading...</i>
  </div>
</li>


다음으로 Stimulus 컨트롤러/app/javascript/controllers/repositories_controller.js를 추가합니다.

import ApplicationController from './application_controller';
import StimulusReflex from 'stimulus_reflex';
export default class extends ApplicationController {
  connect() {
    super.connect();
    StimulusReflex.register(this);
    this.loadRepositories();
  }
  loadRepositories() {
    if (this.isActionCableConnectionOpen()) {
      this.stimulate('Repositories#load_repositories');
    }
    else {
      setTimeout(function () {
        this.loadRepositories();
      }.bind(this), 100);
    }
  }
}


이 컨트롤러에서 주목해야 할 두 가지 중요한 사항입니다. 첫째, 이 Stimulus 컨트롤러를 StimulusReflex에 등록해야 stimulate를 호출할 수 있습니다. 둘째, isActionCableConnectionOpen인지 확인해야 합니다. 그렇지 않으면 기다렸다가 다시 시도하세요.

다음으로 리포지토리를 게으른 로드 작업의 대부분을 수행하는 StimulusReflex을 추가합니다.

class RepositoriesReflex < ApplicationReflex
  delegate :current_user, to: :connection
  delegate :view_context, to: :controller
  def load_repositories
    user = User.new
    user.repositories.build
    form = ActionView::Helpers::FormBuilder.new(:user, user, view_context, {})
    github = Octokit::Client.new(access_token: current_user.token)
    github.auto_paginate = true
    repositories = github.repos({}, query: { type: "any", sort: "asc" })
    morph "#repositories", render(partial: "/users/repositories", locals: { form: form, repositories: repositories })
  end
end


이 반사에서 중요한 몇 가지. 첫째, 부분에는 양식 개체가 필요하므로 ActionView::Helpers::FormBuilder을 사용하여 초기 저장소를 구축하는 사용자를 위한 양식을 만듭니다. view_context 이 필요하므로 위임을 활용하여 컨트롤러에서 액세스합니다. 둘째, Octokit 클라이언트에는 사용자 인증 토큰이 필요하므로 current_user에 액세스할 수 있도록 연결에 대리자를 추가합니다. 세 번째, 전체 page morph 를 트리거하는 대신 selector morph 을 사용하여 id가 #repositories 인 div만 업데이트할 수 있습니다.

마지막으로 /app/views/users/_repositories.html.erb 부분을 추가합니다.

<% repositories.each do |repository| %>
  <%= form.fields_for :repositories, repository do |ff| %>
    <div class="form-check form-check-inline">
      <%= ff.check_box :checked, class: "form-check-input" %>
      <%= ff.label :checked, repository.full_name.downcase, class: "form-check-label mr-2 mb-1" %>
    </div>
    <%= ff.hidden_field :uid, value: repository.id %>
    <%= ff.hidden_field :name, value: repository.name %>
    <%= ff.hidden_field :path, value: repository.full_name %>
    <%= ff.hidden_field :url, value: repository.html_url %>
  <% end %>
<% end %>


그게 다야! 현재 상황은 다음과 같습니다.
  • 초기 양식이 로드되고 Loading... 자리 표시자가 표시됩니다.
  • Stimulusconnect 메서드는 컨트롤러가 처음 로드될 때 호출됩니다.
  • Stimulus 컨트롤러에서 확인isActionCableConnectionOpen한 다음 this.stimulate(‘Repositories#load_repositories’)을 호출하고 그렇지 않으면 기다렸다가 다시 시도합니다.
  • StimulusReflex는 대리자를 사용하여 view_contextcurrent_user에 액세스합니다.
  • StimulusReflex는 ActionView::Helpers::FormBuilder을 사용하여 양식 개체를 만듭니다.
  • 사용자 저장소를 가져오기 위해 GitHub의 API에 대한 외부 호출을 수행합니다.
  • selector morph을 트리거하여 양식 및 리포지토리에 대한 로컬에서 부분 전달을 렌더링합니다.
    그런 다음 StimulusReflex는 #repositories div를 리포지토리 목록을 표시하는 부분으로 바꿉니다.

  • Stimulus은 "컨트롤러, 대상 및 작업 속성으로 HTML을 뿌려주는"강력한 라이브러리입니다. 그리고 StimulusReflex 페이지 업데이트를 수행하도록 서버 측 코드를 트리거할 수 있습니다. 함께 그들은 Rails에 대한 강력한 조합입니다!

    좋은 웹페이지 즐겨찾기