Как мне указать ответ AJAX?
Я погружаю свой палец в Rails3 / JQuery / ненавязчивый JavaScript. Я написал игрушечное приложение, которое делает все, что я хочу, с отключенным JS, теперь я хочу представить javascript, чтобы серверу не приходилось обновлять всю страницу при каждой транзакции.
Вот среда NON-JS Controller/View для создания новой игрушки:
контроллер
class ToysController < ApplicationController
...
def new
@toys = Toy.all
@toy = Toy.new
respond_to do |format|
format.html # new.html.erb
end
end
Просмотры
# ==========
# file: views/toys/index.html.erb
<%= render :partial => 'list', :locals => {:toys => @toys, :target => nil} %>
<%= link_to 'New Toy', new_toy_path, :class => 'new' %>
# ==========
# file: views/toys/new.html.erb
<%= render :partial => 'list', :locals => {:dj_monitors => @toys, :target => @toy} %>
# ==========
# file: views/toys/_list.html.erb
<div class='table-div'>
<div class='body-div'>
<% toys.each do |t| %>
<%= render :partial => 'toy', :locals => {:toy => t} %>
<% end %>
<% if target && target.new_record? %>
<%= render :partial => 'form', :locals => {:toy => target} %>
<% end %>
</div>
</div>
(Прошу прощения за кажущуюся сложность, но все, что делает _list.html.erb, перечисляет все существующие игрушки, и если: target ссылается на новую запись, выводит частичную _form в конце списка.)
# ==========
# file: views/toys/_form.html.erb
<%= form_for(toy) do |f| %>
<div class='column selected'><%= f.number_field :sku %></div>
<div class='column selected'><%= f.text_field :description %></div>
<div class='column selected'>
<%= link_to 'Cancel', toys_path %>
<%= f.submit %>
</div>
<% end %>
ajaxification
В версии с поддержкой javascript мне бы хотелось, чтобы при нажатии на ссылку "новая игрушка" (в index.html.erb) отправлялся XMLHttpRequest, который возвращает только частичную форму, которая будет отображаться на месте. Публикация этой формы также будет стандартной удаленной транзакцией.
Но я не могу понять, как заставить сервер возвращать только форму. Я изменил новый метод ToysController для:
def new
@toys = Toy.all
@toy = Toy.new
respond_to do |format|
format.html # new.html.erb
format.js { render :partial => 'form', :locals => {:toy => @toy} }
end
end
... и включил опцию: remote => true в ссылке [Новая игрушка] в представлении index.html.erb:
<%= link_to 'New Toy', new_toy_path, :class => 'new', :remote => true %>
Теперь мой прокси-сервер отладчик видит GET /toys/new HTTP/1.1
с X-Requested-With: XMLHttpRequest
(это выглядит правильно), но ответ HTTP/1.1 304 Not Modified
Почему он не отображает _form.html.erb?
обновление: избегать ответов "304 не изменены" (не)
Было две проблемы - @Robin решил основную проблему. Другая часть заключалась в том, что я получал ответ "304 Not Modified" - он был технически правильным, поскольку сервер уже отправил форму, - но затруднил отладку.
Поэтому, если вы пытаетесь отлаживать код javascript / ajax, это может помочь удержать вызов 'expires_now' в вашем контроллере, чтобы заставить сервер повторно отправлять страницу во время отладки, например так:
def new
@toy = Toy.new
expires_now
respond_to do |format|
format.html ...
format.js ....
end
end
1 ответ
def new
@toy = Toy.new
respond_to do |format|
format.html { @toys = Toy.all } #you only need to get all toys in this case (and you should add pagination)
format.js
end
end
в new.js.erb
$("#some_div").append("<%= escape_javascript(render "toys/form", :toy => @toy) %>")
Вам нужно будет сделать частичное в format.js
если вы сделали запрос самостоятельно:
$.ajax({
success: function(data) {
$("#some_div").append(data);
}
})