Ajax на рельсах 4

У меня есть приложение, которое позволяет пользователям понравиться сообщение. Когда кому-то нравится сообщение, почтовый запрос работает, но представление не обновляется, если я не обновляю страницу. Я застрял на этом. Это то, что у меня есть до сих пор:

Javascript

$('.favorite').on('click', function() {
 var $heart = $(this).find('.fa');
 $heart.removeClass('fa-heart-o').addClass('fa-heart');
 // POST request to server to create favorite in db
 $.post('/favorites', {
 favorite: { post_id: $(this).attr('data-id') }
 },
 function(data) {
 console.log(data);
 });
});

Контроллер

def create
 post = Post.find_by_id(favorite_params[:post_id])
 if current_user.favorite_posts.include? post
 render json: {}, status: :bad_request
 else
 @favorite = current_user.favorites.new(favorite_params)
 if @favorite.save
 render json: @favorite
 else
 render json: { errors: @favorite.errors.full_messages }, status: :unprocessable_entity
 end
end

конец

Это представление

<% if current_user.favorite_posts.include? post %>
 <span> <%= post.favorites.count %></span>
<% else %>
 <span> <%= post.favorites.count %></span>
<% end %>

Любая помощь приветствуется. Спасибо.

3 ответа

Есть два решения:

  • Вызовите изменение вида с помощью встроенного браузера ajax
  • Используйте функцию Rails UJS для запуска изменения вида на сервере.

Я думаю, что ваша самая большая проблема заключается в том, что у вас нет каких-либо функций для изменения вашего представления по успешному запросу. Два вышеперечисленных варианта - это то, что вам нужно, чтобы заставить его работать, поэтому я подробно расскажу вам о них:

Ajax

Ajax отправит вам запрос; вам все равно придется управлять своим откликом и функциональностью:

$.post('/favorites', { favorite: { post_id: $(this).attr('data-id') }},
.done( function(data) {
 /* Manipulate your view here */
 $("span.fa").text(data);
 console.log("Success");
});

Вы должны помнить, что Ajax - это просто асинхронный запрос. То есть Javascript будет действовать как микро-браузер, отправляя данные на сервер от вашего имени.

Затем он получит ответ от сервера (предположительно содержащий нужные данные)... это ваша работа, чтобы затем управлять вашим представлением с помощью этих данных.

JS

Другой метод, который вы можете использовать, включает систему Rails UJS. То есть вы можете запускать javascript шаблоны ERB после запуска действия вашего контроллера.

Это даст вам возможность манипулировать вашим представлением по мере необходимости, без редактирования вашего текущего javascript:

$.post('/favorites', { favorite: { post_id: $(this).attr('data-id') }}
 .done( function(data) { console.log(data); });
#app/controllers/favourites_controller.rb
class FavouritesController < ApplicationController
 def create
 ...
 respond_to do |format|
 if @favorite.save
 format.js #-> invokes /views/favourites/create.js.erb
 format.json { render json: @favorite }
 else
 format.js
 format.json { render json: { errors: @favorite.errors.full_messages }, status: :unprocessable_entity }
 end
end

Затем вы сможете использовать app/views/favourites/create.js.erb для управления вашим видом:

#app/views/favourites/create.js.erb
$("span.fa").hide();


Сделайте это: -

var new_count;
new_count = function() {
 # your script
};
$(document).ready(new_count);
$(document).on('page:load', new_count);

Эта проблема возникает из-за turbolink checkthis


Вместо

function(data) {
 console.log(data);
 });

Вы должны обновить свое представление. Вероятно, вы должны проверить наличие ошибок, а если их нет, обновите содержимое своего диапазона, используя селектор jQuery $( "... span.fa" ).text(new_count).

При таком подходе вы можете вычислить значение new_count как (previous_count_in_the_span + 1), но вы можете вернуть значение счета в свой ответ, если это не вызовет проблемы с производительностью.

licensed under cc by-sa 3.0 with attribution.