开发者

Rails 3.0/3.1, JQuery & Ajax Best Practices

There are several questions throughout this post all related to the title. The overall theme of the post might be summarized as, "What am I missing/How do you do this better?"

Through the usual methods of Googling/screencasts/APIs, I have just finished learning a beginning-working knowledge of how to use the Rails 3.0-JQuery-Ajax combo.

I am left with some (possibly sizable?) questions. In Railscast 242, Ryan ends up performing the final update to the page by having the following:

$("#products").html("<%= escape_javascript(render("products")) %>");

At first, this seemed super strange, and it still seems a little strange: the index.js.erb template is aware that the index.html page has a '#products' div, and the index.js.erb template itself is what issues the update command? This seems to me to be a slight violation of Separation of Concerns - shouldn't the JS on the index.html page be what actually updates the page with the data that it receives back from the post, as opposed to the script from the server being what actually updates the page? Also, this seems slightly brittle. For whatever stupid reason, if I rename the div on index.html to say, '#products_collection', and forget to change index.js.erb, then my index.html page will still work, but my Ajax update won't. I'd like to know if you think the开发者_运维百科 above points are valid / what to do about them if they are.

If need be, I can explain away those things: If you think of the index action as a whole, then it's no big deal that index.js knows about index.html. They may be closely coupled, but they sort of should/can be. And you any sort of testing would uncover the div rename. fine. But...

Now I come to the idea of going further down the Ajax rabbit hole: Suppose that you load the new form into the index page through an Ajax get, and you then submit it through an Ajax post. Following the same pattern, your create.js.erb file might look something like this:

create.js.erb?

$("#products").prepend("<%=escape_javascript( render 'product_as_table_row', :product => @product))%>");

Now my create action is also aware of what my index page looks like. Hmm...now suppose we also want to do the relatively standard behavior of providing a message to the user through the flash:

create.js.erb?

<% flash.each do |key, value| %>
  $("div#flash").html("<div class='<%=key%>'><%=value%></div>");
<% end %>
$('div#flash div').fadeOut(10000);

$("#products").prepend("<%=escape_javascript( render 'product_as_table_row', :product => @product))%>");

Now, In addition to what seems to me to be closer-than-I'd-like coupling between index and create, I have this big fat flash update in my js template. I don't see how can I abstract this away - Can I wrap this up into a method? Where do i put it? Even if it can be wrapped up into a method, won't every create.js and update.js template need to call that function and isn't that un-DRY? Is this what the purpose of view inheritance in 3.1 is? Do you argue that Ajax makes the flash unnecessary, since the user will now see his product right there on the page?

What about a creation failure? Does this also get thrown into the create.js.erb?

create.js.erb

<% if @thought.new_record? %>
  <%# ??? Throw in Validation-Error Form Updates? Display a Modal Dialog? %>
<% else %>
  $("#products").prepend("<%=escape_javascript( render 'product_as_table_row', :product => @product))%>");
<% end %>

In short, I've learned how to execute get and post requests, but I don't see how to apply an overall Ajax pattern to an entire resource DRY-ly and correctly, or beyond that, throughout my application. What I have come across seems fine for tiny things, but not overall. Unobtrusive JS may be nice in the abstract, but at the moment it is seeming very Obtrusive into much of my application. Having never done Ajax in Rails 2.x, I don't have anything there to build upon. So.. All this seeming sloppyness seems to me like it can't be The Rails Way to do things. What am I missing? Any and all insight appreciated.


You can wrap all of these in functions, and place them in application.js, so that your templates can look like

update_product("<%= escape_javascript(render("products")) %>");

add_product("<%=escape_javascript(render 'product_as_table_row', :product => @product))%>");

etc..

Same goes for updating the flash and error handling


I strongly recommend you have a look at the following article by one of the core members of the rails_ujs team, including all the references at the bottom: rails-2-remote-links-and-forms

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜