Best practices for using AJAX without Rails' built-in helpers?

社会主义新天地 提交于 2019-12-04 16:38:46

Horace, you are correct. You don't need the Rails helpers at all. To achieve unobtrusive JavaScript Nirvana, you will do well to avoid them (sorry Marc!)

Unobstrusive JS means avoiding embedded JS where possible. Indeed, try to keep things loosely coupled, but not entirely decoupled. In the example you gave us, it is easy, because we have a URL from the HREF to work with. Your JS does not need to "know" anything about how to request.

Here is how to send through the link from the HREF's blindly, and get Rails to respond with an ajax response (i.e. no layout).

SOLUTION:

<!------- 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").click(function() { $containing_div = $(e).parents('div.body'); var url = $(this).attr('href'); $.ajax({ beforeSend : function(request) { request.setRequestHeader("Accept", "text/javascript"); }, /* Included so Rails responds via "format.js" */ success : function(response) { $(containing_div).empty.append(response); }, type : 'get', url : url }); return false; });

});

########### 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

This also assumes you have RESTful routes or similar to handle /post/:id

And we're done! I believe there is something in that for all of us. :D

In this case, I don't think you should have the AJAX call at all. You already have the original post's entire content in post.body (you didn't fetch just the 500 characters from the db) Instead of using JQuery to make an ajax call, use it to hide the content past 500 characters and then when the user clicks the 'more' link it shows the rest of the div. You can do this entirely on the client side and save yourself the ajax.

In your partial:

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

Your 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;
}

In my opinion for this kind of problems you should use rails' helpers.

HTML would go like :

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

The more link would be :

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

And the controller would do something like :

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

The other way that could be just as good is to load everything and then hide it :

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>

(the onclick on a div tag might break in IE but this is to give you the idea)

To me that would be the best way to go unless you have a good reason of avoiding rails' helpers.

Hope that helps

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!