#javascript #ajax #ruby-on-rails-4 #partials
#javascript #ajax #ruby-on-rails-4 #частичные
Вопрос:
Я пытаюсь реализовать голосование вверх / вниз за публикацию через AJAX, чтобы пользователям не приходилось обновлять страницу, чтобы увидеть обновленный результат. Однако при нажатии на ссылки для голосования пользователь перенаправляется на страницу, которая отображает только частичный вид. Родительский вид даже не отображается. Как я могу обновить частичный вид на индексной странице без обновления всей страницы? Я подозреваю, что проблема заключается в моем действии контроллера ‘vote’. Вот мой код на данный момент:
/app/controllers/posts_controllers.rb
def vote
value = params[:type] == "up" ? 1 : -1
@post = Post.find(params[:id])
@post.add_or_update_evaluation(:votes, value, current_user)
respond_to do |format|
#I'm guessing the problem lies here.
format.html { render partial: 'score', locals: {post: @post} }
format.js
end
end
/app/views/posts/_score.html.erb
<td id="score_<%= post.id %>"><%= post.reputation_for(:votes).to_i %></td>
<% if user_signed_in? %>
<td>
<%= button_to "Upvote", vote_post_path(post, type: "up"), method: "post", class: "btn btn-success", remote: true %>
</td>
<td>
<%= button_to "Downvote", vote_post_path(post, type: "down"), method: "post", class: "btn btn-danger", remote: true %>
</td>
<% end %>
/app/views/posts/score.js.erb
$('#score_<%= post.id %>').html("<%= escape_javaScript render partial: 'score', locals: {post: @post} %>");
/app/views/posts/index.html.erb
<% @posts.each do |post| %>
<%= render partial: 'score', locals: {post: post} %>
...
<% end %>
/app/assets/javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require bootstrap.min
//= require turbolinks
//= require_tree .
Комментарии:
1. Я предполагаю, что он не проходит через javascript, а ссылка — это просто обычный якорь.
2. «Ссылка» — это Rails
button_to
. Обратите внимание, что я добавилremote: true
атрибут к кнопке. Есть идеи, как устранить это?
Ответ №1:
js
В ветке вашего ответа отсутствует блок, в котором указывается, какой вид должен быть отображен:
respond_to do |format|
format.html { render partial: 'score', locals: {post: @post} }
format.js { render partial: 'score', locals: {post: @post} }
end
В противном случае rails по умолчанию будет отображать vote.js
, поскольку это имя вашего метода контроллера. И, возможно, это просто опечатка, но ваш файл должен быть назван _score.js.erb
(частично), точно так же, как версия HTML.
Обновить
Еще раз просмотрев ваш код, возможно, достаточно просто переименовать score.js.erb
в vote.js.erb
, поскольку вы отображаете _score
частичное там.
И с точки зрения дизайна, самым чистым и сухим решением было бы пропустить блоки для format
вызовов и иметь файлы, подобные таким:
# posts_controllers.rb
def vote
value = params[:type] == "up" ? 1 : -1
@post = Post.find(params[:id])
@post.add_or_update_evaluation(:votes, value, current_user)
respond_to do |format|
format.html # this renders vote.html.erb
format.js # this renders vote.js.erb
end
end
# vote.html.erb
<%= render 'score', locals: { post: @post } %>
# vote.js.erb
$('#score_<%= @post.id %>').html("<%= escape_javaScript render partial: 'score', locals: { post: @post } %>");
# _score.html.haml
<td id="score_<%= post.id %>"><%= post.reputation_for(:votes).to_i %></td>
<% if user_signed_in? %>
<td>
<%= button_to "Upvote", vote_post_path(post, type: "up"), method: "post", class: "btn btn-success", remote: true %>
</td>
<td>
<%= button_to "Downvote", vote_post_path(post, type: "down"), method: "post", class: "btn btn-danger", remote: true %>
</td>
# index.html.erb
<%= render 'score', collection: @posts, as: :post %>
Комментарии:
1. Я внес изменения, которые вы указали в обновлении в своих сообщениях. Однако переход к /posts приводит к неопределенной локальной переменной или методу `post’ для #<#<Class:0x49bbfe8>:0x4760bb0> .
2. Кроме того, я вместо этого попытался отменить эти изменения и выполнить только те изменения, которые вы предложили перед редактированием. Опять же, в браузере отображается только частичный вид.