开发者

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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜