Marcio Trindade

Pjax

Não faz muito tempo que escutei falar de pjax uma técnica que une ajax + pushState e que o Chris Wanstrath do github difundiu criando o jquery-pjax, recentemente o Ryan Bates do railscts.com publicou um epsódio mostrando como você pode utiliza-la com o rails.

Você já deve ter visto a arvore de códigos (source tree) que o github utiliza, quando você clica em um arquivo ou diretório ele atualiza o conteúdo via ajax e altera a url pra que você possa copiar e mandar pra outras pessoas sem o uso de ancoras que hoje em dia é o uso comum. Isso mantém o histórico de navegação dos navegadores funcionando.

Claro que esta técnica tem suas limitações, principalmente por ser uma tecnologia nova e não funcionar em todos os navegadores, além de ser específica para certos tipos de conteúdos.

Como este blog é uma aplicação simples, resolvi mais uma vez usa-lo como laboratório e testar o pjax em açāo, depois de assistir o screencast do railscasts eu apliquei uma versão basica, só pra ver funcionando em 3 minutos. Resolvi mudar a implementação e corrigi alguns problemas como outros eventos no javascript e em menos de 10 minutos já estava tudo funcionando como eu queria graças a ajuda da gem rack-pjax.

Veja como é simples

Adicione a gem rack-pjax no seu projeto.

Gemfile
gem 'rack-pjax'

Adicione o rack middware na inicialização de seu projeto.

config/application.rb
module Blog
  class Application < Rails::Application
    config.middleware.use Rack::Pjax
    # config default
  end
end

Faça o download do javascript do Chris e coloque no seu app/assets/javascripts:

console
curl https://raw.github.com/defunkt/jquery-pjax/master/jquery.pjax.js > app/assets/javascripts/jquery.pjax.js

Intancie ele na sua aplicação, no meu caso ficou assim.

app/assets/javascripts/application.js
//= require jquery
//= require jquery.pjax
//= require blog

Adicione o atributo data-pjax-container no elemento que você quer que seja atualizdo

app/views/layouts/application.html.slim
  #content-body data-pjax-container=""
  = yield(:title)
  = yield

E pra finalizar basta chamar o método pjax para um seletor jQuery e passar como atributo o container que deseja que seja atualizado.

app/assets/javascripts/blog.coffee
jQuery ->
  $('.pjax').pjax('[data-pjax-container]')

No meu caso como estava usando para todo o conteúdo do site eu precisei voltar o scoll da página para o topo, então adicionei este código abaixo:

app/assets/javascripts/blog.coffee
$('#wrapper').bind 'pjax:end', ->
  window.scroll(0,0)
jQuery ->
  $('.pjax').pjax('[data-pjax-container]')

Outros eventos que eu tinha utilizando o método click deixaram de funcionar, porém pra corrigir bastou alterar para o live que fica escutando sempre, mesmo depois de atualizar partes do conteúdo.

Recomendo que você utilize o pjax, afinal é muito simples de implementar, diminui o trafego na rede, melhora a performance da aplicação apra os usuário e para os navegadores que não tem supporte tudo continua funcionando normalmente. Não é sempre que você conseguirá implementar em todo conteúdo como foi feito aqui no blog, porém implemente mesmo que seja algo simples como a árvore de códigos do github, mas tome cuidado pra não quebrar nenhuma funcionalidade javascript.