问题
I have the following interface for a baseball-draft oriented hobby project of mine that lets a team owner build a set of criteria to rank players on:
Clicking the attributes will add that attribute to the list, give it an importance factor and a sort direction.
In Rails 2 and Rails 3 (with the prototype helpers) - I did this by having the following:
<div class="rankingvaluecloud">
<ul>
<% @rankingattributes.each do |attributename| %>
<li><%= add_ranking_attribute_link(attributename) %></li>
<% end %>
</ul>
</div>
<div id="rankingattributes">
</div>
Where "add_ranking_attribute_link(attributename)" is:
def add_ranking_attribute_link(attributename)
link_to_function attributename do |page|
page.insert_html :bottom, :rankingattributes, :partial => 'ranking_attribute', :locals => {:attributename => attributename }
end
end
I'm converting this to jquery, but I'm not sure the best way to do it - mainly because of the loop involved. I can do this:
<div class="rankingvaluecloud">
<ul>
<% @rankingattributes.each do |attributename| %>
<li><%= link_to(attributename,'#',:class => 'attributeappend', :onclick => "$('#rankingattributes').append('#{escape_javascript(render(:partial => 'ranking_attribute',:locals => {:attributename => attributename}))}')") %></li>
<% end %>
</ul>
</div>
<div id="rankingattributes">
</div>
Which is basically just replacing the link_to_function. But is there a better way? The ujs way would have me doing something like:
$(".attributeappend).click(function() {
$('#rankingattributes').append('#{escape_javascript(render(:partial => 'ranking_attribute',:locals => {:attributename => attributename}))}')
});
But that doesn't work out outside the loop because of the attributename handling. I honestly get a bit lost mixing in erb and javascript - and don't know a good way of passing attributename as a param to the javascript function to insert back into the render partial without a fragile cascade of debugging erb and javascript syntax errors, both of which are frustrating to debug.
There has to be a better way though (and I'm sure there's a better interface for this, suggestions welcome!).
回答1:
I'd do this in the view:
link_to 'attributename','#',:class => 'attributeappend'
and then the matching bit of js would be
$(".attributeappend").click(function() {
$('#rankingattributes').append($('#template').html().replace(/toReplace/g, $(this).text());
return false;
});
This assume that you have an invisible element on the page with id template
, something like
<div id="template">
Attribute: toReplace
...
</div>
When you click on the link, the javascript fires. It grabs the html from inside the template and replaces all the instances of toReplace with the text it has extracted from the link and appends it to the element with id ranking attributes
.
If you wanted the text in the link to be different to the actual value that is replaced in this way you could add data- attributes on your links with the correct value.
来源:https://stackoverflow.com/questions/8617384/whats-the-best-ujs-way-of-refactoring-link-to-function