After reading David Heinemeier Hansson's blog post about server-generated javascript I decided to review the way I approach making AJAX calls in my Rails applications. What David suggests is to create a .js.erb
template, which is just javascript embedded with ruby code generated on the server, and not to do any DOM manipulation in the client-side javascript.
Another approach is of course to simply do everything on the client-side, and (for example) return a JSON object representing the updated object from the server and use javascript to do all DOM manipulation.
I dislike the first approach for two reasons:
1) I use HAML and Coffeescript in my application, and feel that by using vanilla javascript and ERB would uncecessarily bloat my code-base with code of a different language (maybe it's possible to create .coffee.haml templates rather than js.erb, I don't know)
2) I really don't like the idea of 'littering' my view folder with what is essentially javascript files, with a little bit of ruby embedded.
The second approach, as David talks about in his blog post, relies very heavily on client-side javascript, which could lead to bloated client-side javascript code, and possibly the need for client-side templates, which in worst case scenarios could mean almost doubling the number of templates.
The approach I decided to go for (and want to ask whether or not is completely stupid way to go about this) is the following:
1) Set the remote: true
flag to make links and forms utilize AJAX to post to the server.
2) In my controller, handle everything as html, and simply render without layout should the request be an AJAX request: render partial: '<partial-name>', layout: false if request.xhr?
. This simply returns the HTML of the partial, with the ruby code evaluated.
3) In an asset javascript file (for instance <partial-name>.js.coffee
) listen to ajax:success
and append the HTML from the response.
I like this approach because (in my rather simple application) this allows me to keep all my code in HAML/Coffeescript, and avoids any javascript templates.
I realize this problem might take on a different character should the complexity of the application grow, but I still feel that it's a valid question: is this a bad way to go about implementing an AJAX-based architecture for a Rails application (and if so, why? i.e. is there a reason why returning HTML instead of JSON from an AJAX call is a bad idea?) or is this something I should continue to utilize?
Thank you :-)
You can't return "true" until the ajax requests has not finished because it's asynchron as you mentioned. So the function is leaved before the ajax request has finished.
The $.ajax() function returns the XMLHttpRequest object that it creates. Normally jQuery handles the creation of this object internally, but a custom function for manufacturing one can be specified using the xhr option.
You can store your promise, you can pass it around, you can use it as an argument in function calls and you can return it from functions, but when you finally want to use your data that is returned by the AJAX call, you have to do it like this: promise. success(function (data) { alert(data); });
AJAX = Asynchronous JavaScript And XML. AJAX is not a programming language. AJAX just uses a combination of: A browser built-in XMLHttpRequest object (to request data from a web server) JavaScript and HTML DOM (to display or use the data)
Your approach seems to me quite accurate. However I would change 1 pt. Instead of using remote: true, I would use jQuery ajax call directly.
$(function(){
$('#some_link').click(function() {
$.ajax({
// some parameters here
})
.done(function(data){
$('div').html(data);
});
});
});
if you use remote: true it sends a js request instead of html request.
then when the controller method is executed, it looks for the js.erb or js.haml file which has the same name as the controller action that just finished executing.
in this file you can write 'js' code to perform any action that needs to be done after the controller action has completed executing like changing a partial or updating view, etc.
if you have a function in javascript asset file, you can call that function as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With