Rails中Ajax响应渲染Partial时实例变量未更新问题求助
问题根源
- ERB代码是服务器在页面首次加载时解析执行的,你Ajax成功回调里的
<%= @ingredients %>和render partial语句,在页面加载阶段就已经基于RecipesController#new里的空数组@ingredients生成了静态内容,不会在Ajax请求后重新解析。 - 当前
IngredientsController#search方法没有输出有效响应,默认会尝试查找对应的视图模板,而你未定义该模板,导致前端拿到的res并非预期的食材数据。
解决方案1:控制器直接渲染Partial返回HTML
这种方式最直接,让IngredientsController直接渲染目标Partial并返回HTML,前端直接插入模态框即可。
- 修改
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'。
- 修改前端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。
- 修改
IngredientsController:
class IngredientsController < ApplicationController def search @ingredients = Tools.searchForIngredient(params['name']) // 返回指定字段的JSON数据 render json: @ingredients.as_json(only: [:name, :brand, :description]) end end
- 修改前端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
相关产品推荐
相关产品推荐

