Я много читал о Rails, AJAX и 5.1 Unobtrusive javascript. Это многое объясняет, например, об ответе на вызовы AJAX в версии Rails с помощью файла .js.
Однако то, что я хочу сделать, это не обслуживать весь файл .js, а просто обновлять элемент после запроса <% link_to %> POST. Насколько я понимаю, настройка remote: true отправляет его как запрос AJAX.
По сути, у меня есть «Пост», который пользователь может лайкнуть с помощью связанной кнопки «Нравится». Это отправляет запрос POST контроллеру «Post», который обновляет сообщение до понравившегося и добавляет лайк к посту.
К сожалению, чтобы увидеть эффект понравившегося поста (а именно, ссылка меняет цвет, а также значок с потрясающим шрифтом), вам нужно обновить страницу. Я в основном хочу, чтобы он обновлялся без необходимости обновления.
Я «думаю», основываясь на том, что я прочитал, мне нужно сделать respond do и ответить через .js на запрос файлом .js в представлении, которое я хочу обновить (например, если действие контроллера называется «нравится», может быть, файл like.js.erb в представлении, которое я обновляю?). Но я не хочу обслуживать целую новую страницу... или это просто запустит .js?
Тогда я мог бы сделать что-то вроде $('i.fa-icon#id').style.color = "blue" или что-то в этом роде? (Я предполагаю, что могу отправлять данные с контроллера в файл .js.erb?). Не уверен, что это лучший способ сделать это, у рельсовых элементов много раз есть какой-то data-attribute или что-то в этом роде (я все еще новичок в этом).



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Не уверен, что понимаю вопрос, но если вы хотите обновить кнопку «Мне нравится»:
Что вы хотите сделать, так это добавить прослушиватель событий к кнопке, и при нажатии он отправляет запрос POST на любой маршрут, обрабатывающий лайки (с правильными параметрами), и ваш контроллер должен ответить подобным объектом (или что-то еще в базе данных сохраняется). Попросите ваш почтовый запрос об успешном методе захватить кнопку «Нравится» и изменить ее на то, что вы хотите, чтобы она выглядела.
$(“#like-btn”).click(function(){
Rails.ajax({
url: "/some/url/to/like/controller",
type: "post",
data: [your post data],
success: function(data) { $(`#${ data[“btn-name”] }`).attr(“color”, “blue”; }
})
}
Вы можете вставить этот скрипт прямо внизу html-страницы
Вам не обязательно делать это именно так, просто дайте вам представление о том, как настроить шаблон, чтобы JavaScript и Ajax обрабатывали запрос на публикацию и обновление внешнего интерфейса вместо использования кнопок html.
Да, это просто скрипт, вы можете поместить его в файл erb (в теге <script>) или добавить в файл JavaScript (если вы его загружаете). Я также рекомендую обернуть весь скрипт в прослушиватель событий «DOMContentLoaded».
Ваше описание совершенно верно!
В отличие от другого ответа, вам даже не нужен прослушиватель событий, но, как вы сказали, вы хотите иметь respond_to в контроллере.
Итак, начиная с html:
# post/index.html.erb
<div id = "like-button">
<%= button_to "Like this post", post_path(@post), remote: true %>
</div>
Обратите внимание, что при использовании помощника button_to по умолчанию это будет запрос POST.
Если вы щелкнете по нему, он перейдет к controller#update, который вы хотите изменить на это:
#posts_controller.rb
...
def update
@post.save
respond_to do |format|
format.html { redirect_to post_path(@post) }
format.js # <-- will render `app/views/posts/update.js.erb`
end
end
Примечание: format.html отображается, когда JS отключен.
Теперь в сценарии, когда JS включен, он выполняет файл app/views/posts/update.js.erb. Это может выглядеть так:
const likeButton = document.getElementById('like-button');
likeButton.innerHTML = '<%= j render "posts/liked-link", post: @post %>';
Что делает последняя строка? Конечно, вы можете изменить стиль непосредственно с помощью JavaScript, но вы также можете отобразить новый партиал — и вы создадите его в новом html-файле:
# app/views/posts/liked_link.html.erb
<div id = "like-button ">
<p>"You liked this post!" </p>
</div>
Я только что изменил ссылку/кнопку на p сейчас, но, конечно, вы можете делать все, что хотите.
Надеюсь, это имеет смысл :)
Вау, даже не знал о button_to! Узнавать что-то новое каждый день, я думаю. Кстати, что с буквой «j» в ссылке рендеринга в опубликованном вами js-файле? Примечание: как бы вы визуализировали новый партиал? Я предполагаю так же, как и в рельсах. Просто визуализировать любой фрагмент в файле .js.erb?
Таким образом, рендеринг отображает партиал, который находится в view/posts/liked_link.html.erb, он может быть таким же коротким, как последний фрагмент кода, который я опубликовал, поскольку он просто заменит div кнопки. j экранирует «возврат каретки и одинарные и двойные кавычки для сегментов JavaScript» api.rubyonrails.org/classes/ActionView/Helpers/… Но я нашел здесь лучший ответ: stackoverflow.com/a/12518779/9595653
@Клара Спасибо за этот замечательный пост, он приблизил меня к тому, чего я пытаюсь достичь. У меня есть уникальная проблема в том, что я пытаюсь обновить значение одного <td> в большой таблице. Я не смог понять, как конкретно настроить таргетинг на уникальный элемент, который мне нужно обновить. Если я добавлю какой-то атрибут data-*, который я отправлю контроллеру, есть ли способ получить к нему доступ в ответе JS? В лучшем случае идентификатор элемента является динамическим, и я не могу понять, как выбрать правильный. Любая помощь очень ценится!
Ты почти там. Назначьте элементу атрибут динамических данных следующим образом: <td data-record-id = "<%= record.id %>">, а затем запросите его в файле js.erb следующим образом document.querySelector("[data-record-id='<%= @record.id %>']"), учитывая, что в соответствующем контроллере вы назначили эту переменную экземпляра (потому что вы знаете, что вы получаете файл js, потому что вы идете через контроллер). Надеюсь, поможет!
Да, в основном я хочу обновить кнопку после прохождения запроса ajax (например, изменить цвет, чтобы обозначить, что пользователю понравился пост). Значит, это может идти прямо в файле .erb?