问题
A number of Rails views in our application populate themselves via AJAX, and the first rendering of their data comes from an javascript call that runs on jquery's $(document.ready)
event. The views we are interested in for this essentially show a list of tabular data (e.g. an inbox, a list of search results, and so on).
We want to pre-render the first page of results without having to make the AJAX call, but we want to be able to re-populate the view without reloading the whole page. This isn't difficult, but it seems to require writing separate bits of code in different parts of the app that do the same thing: once in the view to draw the initial set of data (from the initial render
call) and once more in the Javascript to draw new sets of data (dynamically clearing out the old DOM and replacing it with fresh HTML).
Currently the javascript clones a hidden (with style='display: none'
) template element (usually a div
), sets the value of each field, and adds the new element to the DOM. This works well, but if we want to pre-populate the view before rendering we have to write another copy of the template object in a rubyfied ERB block (e.g. @messages.each do |m|
). If the template is changed, then the code in the ERB block has to be changed to match -- not very DRY.
Is there a better way? If so, what is it?
Thanks
Tom
回答1:
In your document(ready), you can explicity make the first AJAX call that isn't tied to an event handler. Or similarly, you can explicitly trigger the event handler.
Uninitialized index view:
index.html.haml (initial)
.span12
#book-table
Now here is the DRYed up partial that will be used to populate div#book-table
_table.html.haml
%table
%tr
%th Title
%th Author
- books.each do |book|
%tr
%td= link_to book.title, book_path(book)
%td= book.author
Next you'll have JS that responds to it. Note that what this is doing is rendering the partial during an AJAX call to the index action.
index.js.erb
$('#book-table').html('<%= escape_javascript(render(partial: "table", locals: { books: @books })) %>');
We now need to adjust the index view to initialize to this view:
index.html.haml (final)
:javascript
$(document).ready (function() {
$.get("/books.js");
});
.span12
#book-table
As you can see, the document.ready does an initial AJAX call, hitting your .js.erb and populating the div without explicitly populating the div in the .html.haml
来源:https://stackoverflow.com/questions/10565820/pre-render-ajax-populated-view-in-a-dry-way