Pergunta

No meu aplicativo de blog, algumas postagens aparecem como trechos - ou seja, o usuário vê os primeiros (digamos) 500 caracteres e pode clicar em um link para visualizar a postagem inteira.Aqui está a parcial relevante:

<% href = url_for post_path(:id => post) %>

<h1 class="title"><%= post.title %></h1>
<h2 class="published_on"><%= post.author %> wrote this <%= time_ago_in_words(post.published_on)%> ago</h2>
<div class="body">
  <% if defined?(length) %>
    <%= truncate_html(post.body, :length => length, :omission => "&hellip;<h1><a class='more' href=\"#{href}\">Click here for more!</a></h1>") %>
  <% else %>
    <%= post.body %>
  <% end %>
</div>

No entanto, em vez de "Clique aqui para mais!" Levando o usuário a uma página separada, gostaria que ela preencha o restante da postagem em linha.Atualmente, estou implementando isso colocando o trecho acima na seguinte div:

<div class="post" id="post_<%= post.id %>">
  <%= render :partial => 'post_content', :locals => { :post => post, :length => 500 } %>
</div>

Eu então uso o id dessa div no meu application.js para fazer o AJAX:

$(document).ready(function() {

  $("a.more").click(function() {
    var url = $(this).attr('href');
    var id = url.split("/")[2]
    $.get(url, null, function(data) {
      $("#post_" + id).html(data);     
    });
    return false;
  });

});

Obviamente, isso é nojento - não quero que meu javascript dependa da localização do ID da postagem no href do link, mas não conheço outra maneira de o javascript saber qual postagem está recebendo e, portanto, em qual div o conteúdo deve ser inserido.

Qual é a melhor maneira de conseguir isso?Devo voltar a usar os auxiliares AJAX do Rails?

Foi útil?

Solução

Horácio, você está correto.Você não precisa dos ajudantes do Rails.Para alcançar o JavaScript Nirvana discreto, você fará bem em evitá-los (desculpe, Marc!)

JS discreto significa evitar JS incorporado sempre que possível.Na verdade, tente manter as coisas fracamente acopladas, mas não totalmente dissociadas.No exemplo que você nos deu é fácil, pois temos uma URL do HREF para trabalhar.Seu JS não precisa “saber” nada sobre como solicitar.

Aqui está como enviar cegamente o link do HREF e fazer com que o Rails responda com uma resposta ajax (ou seja,sem layout).

SOLUÇÃO:

<!------- Your HTML ------>
<h1 class="title">Schwein Flu Strikes Again</h1>
<h2 class="published_on">B.Obama wrote this 2 seconds ago</h2>
<div class="body">
    SUMMARY SUMMARY
    <h1><a class='more' href="/post/1234">Click here for more!</a></h1>
</div>
/********* Your JavaScript ***********/
$(document).ready(function() {

$ ("a.more"). Clique (function () {$ contening_div = $ (e) .parents ('div.body');var url = $(this).attr('href');$ .ajax ({beforesend:function(solicitação) { request.setRequestHeader("Aceitar", "texto/javascript");}, / * Incluído SO Rails responde via "format.js" * / success:function(resposta) { $(containing_div).empty.append(response);}, tipo :'Get', URL:url});retorna falso;});

});

########### Your Controller ###########
def show
  @article = Post.find(param[:id])
  respond_to do |format|
    format.html { render :action => "show" and return  }
    format.js { render :partial => "post_content", :layout => false and return }
  end
end

Isso também pressupõe que você tenha rotas RESTful ou similares para lidar com /post/:id

E terminamos!Acredito que há algo nisso para todos nós.:D

Outras dicas

Neste caso, eu não acho que você deve ter a chamada AJAX em tudo. Você já tem todo o conteúdo do post original em post.body (você não buscar apenas os 500 caracteres do db) Em vez de usar JQuery para fazer uma chamada ajax, usá-lo para ocultar o conteúdo passado 500 caracteres e, em seguida, quando o usuário clica no link 'mais' que mostra o resto do div. Você pode fazer isso inteiramente no lado do cliente e salve-se o ajax.

Em sua parcial:

<div class="body">
  <%= post.body %>
</div>

Seu JQuery:

var fullText = $('div.body').html();
$('div.body').html(fullText.slice(0,499) + '<a class="more" href=\"#\">Click here for more!</a>');
$('a.more').live('click', function(event) {
  this.parent().html(fullText);
  return false;
}

Na minha opinião para este tipo de problemas você deve usar ajudantes trilhos.

HTML iria como:

My post bla bla bla <span id="more_of<%=post.id%>">more</span>

O mais ligação seria:

<%= link_to_remote( "more",:update => "more_of_#{your_post.id}",:url =>{:controller => "myposts", :action=>"show_more", :id => your_post.id}, %>

E o controlador faria algo como:

post = Post.find_by_id(params[:id])
render :text => post.content.slice(100..post.content.size) 

A outra forma que poderia ser tão bom é carregar tudo e depois escondê-lo:

bla bla bla this is my post blah <div style="display:none" onclick="this.style.display='block';">and this is the rest of the article</div>

(o onclick em uma tag div pode quebrar no IE, mas isso é dar-lhe a idéia)

Para mim, isso seria a melhor maneira de ir a menos que você tenha uma boa razão de evitar ajudantes trilhos.

Espero que ajude

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top