[RAILS] Sortie "élément html de pagenation" de manière asynchrone avec kaminari

Si vous recherchez "kaminari asynchrone", vous trouverez un moyen d'afficher la "page liée" de la pagination de manière asynchrone. Ceci est également introduit dans READ ME de kaminari. https://github.com/kaminari/kaminari

Au lieu de cela, il s'agit d'une introduction sur la façon de générer ultérieurement l '«élément html de pagination» de manière asynchrone. Je n'ai pas trouvé grand-chose dans la recherche. image.png (↑ Élément html Pagenation)

Pourquoi de manière asynchrone?

Lorsque vous sortez normalement l'élément de pagination avec kaminari, écrivez-le sous la forme <% = paginate (@users)%> dans la vue. Cependant, afin de savoir quelle page est la dernière page, une "requête pour obtenir le nombre total d'enregistrements" est lue.

SELECT COUNT(*) FROM users;

Dans ce cas, cela semble léger, mais si vous ajoutez diverses conditions de recherche, ce sera une requête lourde. Par conséquent, le motif est que je souhaite afficher les éléments de pagination de manière asynchrone.

la mise en oeuvre

Tout d'abord, je vais mettre l'image dans son ensemble. Dans Rails, il est supposé être la page d'index du modèle User.

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

html: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>

Commentaire

Le flux de traitement sera expliqué dans l'ordre. Tout d'abord, lorsqu'une requête html arrive à l'action d'index du contrôleur des utilisateurs, ajoutez la méthode .without_count au modèle, puis transmettez-la à la vue.

format.html { @users = users.without_count }

Avec cette méthode, la "requête pour obtenir le nombre total d'enregistrements" mentionnée précédemment ne sera pas émise **. Un html sans éléments de pagination est renvoyé et le processus de synchronisation est terminé.

De là, il est asynchrone. Le html renvoyé (javascript in) demande l'élément de pagenation de manière asynchrone. À ce stade, définissez l'URL sur location.pathname + '. Json' + location.search; Envoyez "URL avec juste la fin du chemin de l'URL changé en json". Si le chemin d'origine est / users? Age = 10, le chemin à envoyer est / users.json? Age = 10.

La requête envoyée est également envoyée à l'action d'index du contrôleur utilisateurs. Puisque l'URL a .json, respond_to est appelé format.json.

format.json { render :json => view_context.paginate(users).gsub('.json', '') }

view_context est une méthode qui renvoie une instance de la vue (https://apidock.com/rails/ActionView/Rendering/view_context). Si vous l'utilisez, vous pouvez utiliser la méthode de visualisation du contrôleur etc., et vous pouvez appeler paginate (user). Puisque la variable ʻuser utilisée ici n'a pas without_count, une "requête pour obtenir le nombre total d'enregistrements" sera émise **. C'est un élément de pagination créé par la méthode paginate, mais si le format est json (autre que html), la fin du lien sera .json`. Alors effacez-le avec gsub. Enveloppez la chaîne html terminée dans json et renvoyez-la.

Du côté javascript reçu, attachez-le simplement à l'élément approprié et vous avez terminé.

fetch(path).then(response => response.text()).then(html => {
  paginator.insertAdjacentHTML('afterbegin', html);
})

J'ai pu sortir l'élément de pagination de manière asynchrone. (Dans l'exemple de ↓, le sommeil est inséré)

a.gif

Bon, asynchrone. J'espère que cet article aide quelqu'un.

Recommended Posts

Sortie "élément html de pagenation" de manière asynchrone avec kaminari
Créer une fonction de pagination avec Rails Kaminari