You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails中Ajax响应渲染Partial时实例变量未更新问题求助

问题根源
  • ERB代码是服务器在页面首次加载时解析执行的,你Ajax成功回调里的<%= @ingredients %>和render partial语句,在页面加载阶段就已经基于RecipesController#new里的空数组@ingredients生成了静态内容,不会在Ajax请求后重新解析。
  • 当前IngredientsController#search方法没有输出有效响应,默认会尝试查找对应的视图模板,而你未定义该模板,导致前端拿到的res并非预期的食材数据。
解决方案1:控制器直接渲染Partial返回HTML

这种方式最直接,让IngredientsController直接渲染目标Partial并返回HTML,前端直接插入模态框即可。

  1. 修改IngredientsController:
class IngredientsController < ApplicationController
    def search
        @ingredients = Tools.searchForIngredient(params['name'])
        # 渲染指定Partial,不加载布局,直接返回HTML
        render partial: 'ingredients/ingredient_search_table', locals: { ingredient_array: @ingredients }, layout: false
    end
end

注意:Partial路径需匹配实际存放位置,比如Partial在app/views/recipes下,就改为'recipes/ingredient_search_table'。

  1. 修改前端Ajax代码:
$('.ingredientContainer').on('click', '.searchForIngredient', function(e) {
    e.preventDefault();
    const ingredientName = $(this).parents('fieldset').find('.ingredient-item').val()
    $.ajax({
        method: 'post',
        url: '/ingredients/search',
        data: {
            name: ingredientName
        },
        success: (html) => {
            // 直接将返回的HTML插入模态框
            $('.ingredientSelectionModalBody').html(html)
            $('.ingredientModal').modal({show: true})
        }
    })
})
解决方案2:返回JSON数据,前端动态生成表格

如果希望前后端解耦,可以让控制器返回JSON格式的食材数据,前端自行构建表格HTML。

  1. 修改IngredientsController:
class IngredientsController < ApplicationController
    def search
        @ingredients = Tools.searchForIngredient(params['name'])
        // 返回指定字段的JSON数据
        render json: @ingredients.as_json(only: [:name, :brand, :description])
    end
end
  1. 修改前端Ajax代码:
$('.ingredientContainer').on('click', '.searchForIngredient', function(e) {
    e.preventDefault();
    const ingredientName = $(this).parents('fieldset').find('.ingredient-item').val()
    $.ajax({
        method: 'post',
        url: '/ingredients/search',
        data: {
            name: ingredientName
        },
        dataType: 'json',
        success: (ingredients) => {
            // 动态构建表格HTML
            let tableHtml = `
                <table class="table table-awaken">
                    <thead>
                        <th>Name</th>
                        <th>Brand</th>
                        <th>Description</th>
                    </thead>
                    <tbody>
            `;

            if (ingredients.length > 0) {
                ingredients.forEach(ingredient => {
                    tableHtml += `
                        <tr>
                            <td>${ingredient.name}</td>
                            <td>${ingredient.brand}</td>
                            <td>${ingredient.description}</td>
                        </tr>
                    `;
                });
            } else {
                tableHtml += '<tr><td colspan="3">未找到匹配的食材</td></tr>';
            }

            tableHtml += '</tbody></table>';

            // 插入模态框
            $('.ingredientSelectionModalBody').html(tableHtml)
            $('.ingredientModal').modal({show: true})
        }
    })
})
额外注意事项
  • 确保路由配置正确:在routes.rb中添加post '/ingredients/search', to: 'ingredients#search'
  • 验证Tools.searchForIngredient方法确实返回了正确的食材数组,避免空数据或逻辑错误
  • 方案1中,Partial的ingredient_array变量需与控制器locals中传递的变量名保持一致

内容的提问来源于stack exchange,提问作者Jeremy Thomas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:10:32