在Rails中,如何使用Jquery/Ajax更新一个div?

4

我需要一些关于如何使用Jquery/Ajax更新页面上的一个div而不实际加载页面的指导。在我提问之前,我将提供一些必要的信息。

我有两个模型:

  • Scoreboard 模型 (has_many :teams)
  • Team 模型 (belongs_to scoreboard)

scoreboard#show 页面上,我已经呈现了一个partial来显示所有的 @scoreboard.teams

这个partial会按照以下代码详细说明的方式显示所有的团队:

<div class ="team-list" id="team_<%=team.id%>">
 <div class= "boxin1"><%= team.name %></div>
 <div class= "boxin2"><%= team.win %></div>
 <div class= "boxin2"><%= team.loss %></div>
 <div class= "boxin2"><%= team.tie %></div>
 <span class= "boxin3 btn btn-primary"><%= link_to "Edit", edit_scoreboard_team_path(@scoreboard, team), remote: true %> </span>
 <span class= "boxin3 btn btn-primary"><%= link_to "Del", [@scoreboard, team], remote: true, method: :delete, data: { confirm: "Are you sure you want to delete the team?" } %>
</div>

现在我的问题涉及到“编辑”按钮,点击后会调用ajax请求,弹出一个表单来编辑团队,然后在提交表单后,调用Teams Controller中的更新方法。为了进一步澄清,以下是相关代码:
团队控制器的编辑和更新方法:
  def edit
    @scoreboard = Scoreboard.find(params[:scoreboard_id])
    @team = @scoreboard.teams.find(params[:id])
    respond_to do |format|
         format.html {redirect_to scoreboard_url(@team.scoreboard_id)}
         format.js
     end
   end

    def update
    @scoreboard = Scoreboard.find(params[:scoreboard_id])
    @team = @scoreboard.teams.find(params[:id])
    if @team.update_attributes(team_params)
     respond_to do |format|
         format.html {redirect_to scoreboard_url(@team.scoreboard_id)}
         format.js
     end
    else
     render 'edit'
    end
   end

这里是edit.js.erb和update.js.erb文件的代码,以及澄清它们的操作描述: edit.js.erb
$("#team_<%=@team.id%>").hide();
$("#team_<%=@team.id%>").after("<%= j render 'teamedit'%>");

点击编辑路径链接按钮后,正在编辑的团队的div被隐藏,紧接着渲染出一个名为teamedit的表单。 update.js.erb
$("#edit_team_<%=@team.id%>").hide();
$("#team_<%=@team.id%>").load("scoreboards/show.html.erb"); #help needed here
$("#team_<%=@team.id%>").show();

现在当提交表单后调用更新控制器方法时,使用jquery隐藏表单,我想重新加载之前隐藏的团队div,然后显示其更新后的值。我觉得使用.load() jquery方法可以刷新具有新编辑值的div,但它不起作用。总之,edit.js.erb可以正常工作,但由于代码中的第二行,update.js.erb无法正常工作。div没有以更新值刷新。是否有人可以提供有关不同方法的指导或让我知道我做错了什么?
编辑:
另一个相关的项目。在Teams控制器中的Team_Params方法:
 private

   def team_params
     params.require(:team).permit(:name, :win, :loss, :tie)
   end
3个回答

6

你几乎完成了所有的事情。

唯一剩下的部分是将团队信息放入一个名为 _team.html.erb 的局部文件中:

<div class ="team-list" id="team_<%=team.id%>">
  <div class= "boxin1"><%= team.name %></div>
  <div class= "boxin2"><%= team.win %></div>
  <div class= "boxin2"><%= team.loss %></div>
  <div class= "boxin2"><%= team.tie %></div>
  <span class= "boxin3 btn btn-primary"><%= link_to "Edit", edit_scoreboard_team_path(@scoreboard, team), remote: true %> </span>
  <span class= "boxin3 btn btn-primary"><%= link_to "Del", [@scoreboard, team], remote: true, method: :delete, data: { confirm: "Are you sure you want to delete the team?" } %>
</div>

然后是 update.js.erb 文件:

$("#edit_team_<%=@team.id%>").hide();
$("#team_<%=@team.id%>").load("<%= j render partial: 'team', locals: {team: @team} %>");
$("#team_<%=@team.id%>").show();

谢谢您的回复。我按照您的指示操作了,表单已经隐藏,div也重新显示了。但是,当div显示时,它仍然使用旧的@team值,而不是输入到编辑表单中的值。我还可能做错了什么吗? - kpaul
我能想到的唯一可能是你的 team_params 方法。你能把它也展示一下吗? - dimakura
这里的问题不在于私有性。它可能出现在其他地方,很难说。如果您可以分享您的项目,那么很快就能确定问题所在。 - dimakura

0
你确定你的更新方法有效吗?我会先检查一下。你需要在team_params方法中包含scoreboard_id。

0

ERB

进一步解释了 dimakura 的回答,看起来你需要一些关于 js erb 基础设施 的理解帮助:

注意 respond_to 块中的 format.js;这允许控制器响应您的 Ajax 请求。然后,您有一个相应的 app/views/users/create.js.erb 视图文件,生成实际的 JavaScript 代码,将在客户端执行。

与标准资产管道相反,控制器生成的 JS.erb 允许您使用在控制器中设置的任何实例变量调用 ERB 功能。

因此,您如何“加载”另一个 ERB 视图到您的 JS 中的问题可以使用 ERB 中的 render 方法处理:

#app/views/teams/update.js.erv
$("#team_<%=j @team.id %>").replacewith('<%=j render("scoreboards/show") %>');

目标视图由您决定。似乎 dimakura 使用了部分,您可以选择其中一个。

--

进程

关于您处理新数据的评论,您需要了解在 js.erb 中,您将访问与任何其他控制器操作中相同的数据。

这意味着,如果您没有收到最新的数据,则存在系统性问题。

我建议执行以下操作:

#app/controllers/teams_controller.rb
class Teamscontroller < ApplicationController
   before_action :set_vars

   def edit
     respond_to do |format|
        format.html {redirect_to @scoreboard }
        format.js
     end
   end

   def update
     respond_to do |format|
       if @team.update team_params
         format.html { redirect_to @scoreboard }
         format.js
       else
         format.html { render :edit }
     end
   end

   private

   def set_vars
      @scoreboard = Scoreboard.find params[:scoreboard_id]
      @team = @scoreboard.teams.find params[:id]
   end

   def team_params
     params.require(:team).permit(:name, :win, :loss, :tie)
   end
end

如果这个方法不起作用,通常意味着您的更新过程存在问题(例如update无法正常工作)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接