Rails7收藏功能问题:取消收藏需刷新,如何实时更新data-unfavorite-url?
解决Rails7收藏功能无需刷新页面更新取消URL的问题
问题核心:收藏成功后,心形图标的data-unfavorite-url和data-favorite-id仅在页面刷新时由ERB模板生成,前端未动态更新这两个属性,导致取消收藏的DELETE请求无法定位到正确端点。
1. 修改Stimulus控制器(核心修复)
在收藏成功的回调中,利用后端返回的收藏记录ID动态生成取消URL,并更新到SVG的data属性;取消收藏后清空相关属性:
import { Controller } from '@hotwired/stimulus'; import axios from 'axios'; export default class extends Controller { favorite() { if (this.element.dataset.userLoggedIn === 'false' ) { return document.querySelector(".sign-in-link").click(); } if (this.element.dataset.favorited === 'true') { axios.delete(this.element.dataset.unfavoriteUrl, { headers: { 'ACCEPT': 'application/json' } }) .then((response) => { this.element.dataset.favorited = 'false' this.element.setAttribute('fill', 'none'); this.element.setAttribute('stroke', '#D3D3D3'); // 取消收藏后清空取消URL和收藏ID this.element.dataset.unfavoriteUrl = ''; this.element.dataset.favoriteId = ''; }); } else { axios.post(this.element.dataset.favoriteUrl, { user_id: this.element.dataset.userId, park_id: this.element.dataset.parkId }, { headers: { 'ACCEPT': 'application/json' } }) .then((response) => { const favoriteId = response.data.id; // 动态生成取消收藏的URL const unfavoriteUrl = `${this.element.dataset.favoriteUrl}/${favoriteId}`; this.element.dataset.favorited = 'true' this.element.setAttribute('fill', '#FF6962'); this.element.setAttribute('stroke', 'none'); // 更新取消URL和收藏ID this.element.dataset.unfavoriteUrl = unfavoriteUrl; this.element.dataset.favoriteId = favoriteId; }); } } }
2. 优化ERB模板初始属性
确保未收藏时data-unfavorite-url和data-favorite-id有默认空值,避免前端读取时出现undefined:
<svg data-controller="favorites" data-user-logged-in="<%= user_signed_in? %>" data-user-id="<%= current_user&.id %>" data-park-id="<%= park.id %>" data-favorite-url="<%= api_favorites_path %>" <!-- 添加默认空值处理 --> data-unfavorite-url="<%= current_user && current_user.favorited_parks.include?(park) ? api_favorite_path(current_user.favorites.find_by(park: park)) : '' %>" data-favorite-id="<%= current_user && current_user.favorited_parks.include?(park) ? current_user.favorites.find_by(park: park).id : '' %>" data-favorited="<%= current_user && current_user.favorites.where(park: park).exists? %>" data-action="click->favorites#favorite" fill="<%= current_user && current_user.favorited_parks.include?(park) ? '#FF6962' : 'none' %>" stroke="<%= current_user && current_user.favorited_parks.include?(park) ? 'none' : '#D3D3D3' %>" width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="1.5" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M21 8.25c0-2.485-2.099-4.5-4.688-4.5-1.935 0-3.597 1.126-4.312 2.733-.715-1.607-2.377-2.733-4.313-2.733C5.1 3.75 3 5.765 3 8.25c0 7.22 9 12 9 12s9-4.78 9-12z" /> </svg>
3. 后端控制器确认返回数据
当前后端create动作已返回完整的收藏对象JSON,默认包含id字段,无需额外修改。
修改完成后,用户收藏公园时前端会自动生成取消URL并更新属性,取消收藏后清空属性,全程无需刷新页面即可完成双向操作。
内容的提问来源于stack exchange,提问作者Rebecca
相关产品推荐
相关产品推荐

