Rails x Ajax로 스마트하게 '더 보기 기능' 구현

8275 단어 아약스Rails번개

소개


  • 巷에서 자주 보는 Ajax에서의 「더 보는」기능을 하나의 페이지내에서 복수 종류 설치하는 의뢰가 와, 여러가지 조사했으므로 공유.
  • 완성형으로서는 이런 느낌이 됩니다. (보기 쉽도록 하나씩 내고 싶지만 적당히 수는 바뀝니다)


  • 예비 지식으로 다음을 머리에 넣어야합니다.
  • Kaminari의 페이지 네이션.
  • Rails의 Ajax 통신. ( index.js.erb에 대해)
  • BootStrap4 (뷰의 성형에 사용하고 있을 뿐이므로, 상세하지 않아도 되지만)
  • Slim 템플릿 (3과 유사)

  • 환경


    $ ruby -v
    ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]
    
    $ rails -v
    Rails 5.2.1
    

    준비


  • 다음이 필요합니다.
  • gem 'kaminari'
    # seedを使うなら
    gem 'seed-fu' 
    

    구현



    모델


  • 여기에서는 예로서 DogCat를 사용합니다만, 존재로 있으면 좋기 때문에 구현은 생략합니다.
  • seed-fu 라든가를 사용해, DB에 미리 페이지네이션용의 인스턴스를 만들어 둡시다.

  • 컨트롤러


  • 우선 컨트롤러로부터. 이번 페이지를 sample#index 액션으로 합니다.
  • 이 작업에서는 html 형식(일반)과 js 형식(Ajax)의 두 가지 유형의 요청을 처리합니다.
  • 일반 액세스의 경우 guard ( return unless request.xhr? )로 멈추므로 인스턴스 변수를 받고 페이지를 렌더링하면됩니다.
  • 그러나 Ajax 통신의 경우 guard를 통과하고 params[:type]마다 다른 JS 파일을 실행합니다.
  • JS 파일 중에는, 「특정의 리스트 리스트에 새로운 요소를 Append해, 특정의 「더 보기」버튼을 갱신한다」처리가 들어 있으므로, 건네받은 파라미터에 의해 거동을 바꿀 수가 있습니다 할 수 있습니다.
  • class SampleController < ApplicationController
      def index
        @dogs = Dog.all.page(params[:page]).per(1)
        @cats = Cat.all.page(params[:page]).per(1)
    
        # これ以下はAjax通信の場合のみ通過
        return unless request.xhr?
    
        case params[:type]
        when 'dog', 'cat'
          render "sample/#{params[:type]}"
        end
      end
    end
    

    보기


  • 뷰는 이번 경우, 모두 5개 준비합니다.
  • app/views/sample/
    ├── _cat.html.slim
    ├── _dog.html.slim
    ├── cat.js.erb
    ├── dog.js.erb
    └── index.html.slim
    
  • 기본적으로 Slim를 사용하고 있지만 JS 파일을 작성할 때는 Erb로 작성하는 것이 좋습니다. (조사하면 알겠지만 매우 그리기 어렵다‥‥)
  • 여담입니다만, Slim 사용해도, 확장자에 erb 라고 붙이면 움직여 주므로 매우 살아 있습니다!

  • HTML 포맷 측


    / index.html.slim
    .container.my-5
      .row
        .col-md-6
          #dog-list
            = render partial: 'sample/dog', collection: @dogs
            = link_to_next_page @dogs, 'もっと見る', id: 'more-dog', class: 'btn btn-light w-100', params: { type: :dog }, remote: true
        .col-md-6
          #cat-list
            = render partial: 'sample/cat', collection: @cats
            = link_to_next_page @cats, 'もっと見る', id: 'more-cat', class: 'btn btn-light w-100', params: { type: :cat }, remote: true
    
    / _cat.html.slim, _dog.html.slim (cat -> dogに書き換えるだけ)
    .border.mb-1
      p cat
    
  • 부분 뷰에 관해서는 존재를 확인할 수 있으면 좋을 뿐이므로 적당합니다.
  • 포인트는 다음과 같습니다.
  • 각 목록을 포함하는 大元のDivタグユニークなID를 부여합니다.
  • link_to_next_page 메서드에 ユニークIDtypeパラメーター를 부여합니다.


  • JS포맷측


    / cat.js.erb, dog.js.erb (cat -> dogに書き換えるだけ)
    $('#more-cat').remove();
    $('#cat-list').append("<%= j render partial: 'sample/cat', collection: @cats %>")
    $('#cat-list').append("<%= j link_to_next_page(@cats, 'もっと見る', id: 'more-cat', class: 'btn btn-light w-100', params: { type: :cat }, remote: true) %>")
    
  • 보시다시피 특정 목록에 새 요소를 추가하고 있습니다.
  • Ajax를 호출 할 때마다 "더보기"버튼이 업데이트되고 더 이상 데이터가 없으면 자동으로 렌더링되지 않습니다. 하나님

  • 결론


  • 이런 식으로 상상 이상으로 깔끔하게 Ajax에서의 「더 보기」를 구현할 수 있게 되었습니다.
  • 이번은 1 페이지에 「더 보기」가 2개라고 하는 특수한 경우를 취급했습니다만, 별로 하나라도 전혀 움직입니다.
  • 여러분 좋은 Rails 생활을 👍
  • 좋은 웹페이지 즐겨찾기