One thing I don't understand about unobtrusive javascript
I like the idea of separating functionality and this seems like the way of the future.
But I'm used to integrating javascript inside loops in an embedded language like Rail开发者_运维知识库s ERB or PHP, where I can use the ID of a particular object as a reference in the javascript.
Rails example:
<% @comments.each do |comment| %>
<div id="comment_<%= comment.id %>">
<%= comment.text %>
<% link_to_function "Reply", "$('comment_#{comment.id}').insert(\"#{escape_javascript(render :partial => "_form", :locals => {:comment => comment})}\", {position: 'bottom'});" %>
</div>
<% end %>
This isn't the only time I've ended up wanting to use Ruby methods inside javascript either. I may want to use constants, or call other ruby methods on an object inside a loop user.enabled?
or user.full_name
, or render partials with those objects, etc.
So how is this supposed to be accomplished if all the javascript is in another file or outside the loop? I get that you can iterate through a bunch of divs in javascript using CSS selectors, but this doesn't allow me to call ruby methods on objects.
What am I missing? Thanks!
I think it shold be done with "data-id" parameter as shown in this screencast http://railscasts.com/episodes/229-polling-for-changes
For your particular example you already have the comment ID encoded within the markup because you set the ID attribute of the div
element to the comment ID. So you can hang the JavaScript off that.
Pardon me for using jquery, but web development really sucks without it or similar library
For your first complaint (get current comment), javascript this
works fine for me.
onclick="my_function(this);"
and in js file
my_function = function(target) {
// clicked element passed in
// now, let's get comment element by class
var comment = $(target).parents('.comment');
}
As for second complaint... I never needed it often, but sometimes I include pieces of data in html for use by javascript. Extending previous example:
<div class="comment" comment_id="<%= comment.id %>"></div>
And in my_function
var comment_id = comment.attr('comment_id');
Make your client-side script take an 'options' object as a parameter. Don't use any server-side scripting; put the script in its own .js file.
Then create the 'options' object with a server-side script which outputs js. Include your script and call its entry-point function, passing in your 'options' object.
You just need some more JavaScript knowledge to see power of it, especially jQuery. Your example I would solve like:
<% @comments.each do |comment| %>
<div class="comment">
<%= comment.text %>
<a href="reply.php?id=<%= comment.id %>" class="reply">Reply</a>
</div>
<% end %>
<script type="text/javascript">
$('.comment .reply').click(function(e) {
e.preventDefault();
var url = $(this).attr('href');
var result = url.match(/\?id=(\d+)([^\d]|$)/);
var id = (result && result[1]);
if (id) {
// do whatever you want to do with the id
}
});
</script>
Benefits:
(1) You don't have javascript all over the place
(2) Works without javascript
精彩评论