kaminari에서 "페이지 네이션의 html 요소"를 비동기 적으로 생성
htps : // 기주 b. 코m/카미나리/카미나리
그렇지 않고, "페이지 네이션의 html 요소"를 비동기로 나중에 내는 방법의 소개입니다.
검색해도별로 나오지 않았어요.
(↑ 페이지 네이션의 html 요소)
Gem 버전은
kaminari (1.2.1)
, rails (6.0.3.4)
입니다.왜 비동기로?
보통 kaminari에서 페이지네이션의 요소를 낼 때는 뷰에서
<%= paginate(@users) %>
와 같이 씁니다.그렇지만 이것, 마지막 페이지가 몇 페이지째인지를 요구하기 위해, 「레코드의 전건수를 취득하는 쿼리」가 흐릅니다.
SELECT COUNT(*) FROM users;
이 경우는 가볍습니다만, 여러가지 검색 조건을 붙여 가면 무거운 쿼리가 될 것 같습니다. 그래서 페이지 네이션의 요소는 비동기로 표시시키고 싶다는 것이 동기입니다.
구현
먼저 전체 이미지를 올립니다. Rails에서 User 모델의 index 페이지라고 가정합니다.
routes.rb
resources :users
users_controller.rb
def index
users = User.all.page(params[:page]).per(3)
respond_to do |format|
format.html { @users = users.without_count }
format.json { render :json => view_context.paginate(users).gsub('.json', '') }
end
end
users/index.html.erb
<div id="paginator"></div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const path = location.pathname + '.json' + location.search;
const paginator = document.querySelector('#paginator');
fetch(path).then(response => response.text()).then(html => {
paginator.insertAdjacentHTML('afterbegin', html);
})
})
</script>
해설
처리의 흐름을 순서대로 설명합니다. 먼저 users 컨트롤러의 index 액션에 html 요청이 오면 모델에
.without_count
메서드를 붙인 다음 view로 전달합니다.format.html { @users = users.without_count }
이 메소드를 붙이면, 방금 싣고 있는 「레코드의 전건수를 취득하는 쿼리」가 발행되지 않게 됩니다.
페이지 네이션 요소가없는 HTML이 반환되고 동기화 처리가 끝납니다.
여기에서 비동기입니다. 돌려준 html(내의 javascript)에서는, 페이지네이션의 요소를 비동기로 요구합니다.
이때 URL을
location.pathname + '.json' + location.search;
'URL 경로의 끝을 json으로 바꾼 URL'을 보냅니다. 원래 경로가 /users?age=10
이면 보내는 경로는 /users.json?age=10
입니다.전송된 요청은 users 컨트롤러의 index 액션으로도 전송됩니다.
URL 에
.json
가 붙어 있으므로 respond_to
는 format.json
쪽이 불립니다.format.json { render :json => view_context.paginate(users).gsub('.json', '') }
view_context
는 뷰의 인스턴스를 반환하는 메서드입니다( htps : // 아피도 ck. 코 m / 라이 ls / 아 c 치 온 ぃ え w / 렌데 린 g / ぃ ぃ 에 w_ 이렇게 xt ). 이것을 사용하면(자) 뷰의 메소드를 컨트롤러등으로부터 사용할 수가 있어, paginate(user)
를 호출할 수 있습니다.여기서 사용하는 변수
user
에는 without_count
가 붙지 않으므로 "레코드의 총 수를 얻는 쿼리"가 발행됩니다.paginate
메소드로 만들어진 페이지네이션 요소입니다만, format이 json이면(html 이외라고), 링크의 말미가 .json
가 되어 버립니다. 그러므로 gsub로 지웁니다.완성된 html 문자열을 json으로 싸서 반환합니다.
받은 javascript 측에서는, 그것을 적당한 요소에 붙이면 완료입니다.
fetch(path).then(response => response.text()).then(html => {
paginator.insertAdjacentHTML('afterbegin', html);
})
비동기적으로 페이지네이션 요소를 낼 수 있었습니다.
(↓의 예에서는 sleep를 넣고 있습니다)
좋아, 비동기.
이 기사가 누군가의 도움이되는 경우입니다.
Reference
이 문제에 관하여(kaminari에서 "페이지 네이션의 html 요소"를 비동기 적으로 생성), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/tetetratra/items/ff66bdfa4e4bb2758a5a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)