javascript - Rails AJAX 请求 Controller 方法,然后调用 javascript 函数

标签 javascript jquery ruby-on-rails ruby ajax

我查看了数十个堆栈溢出帖子,但没有找到有效的解决方案,这就是为什么我要寻求一个其他方面有据可查的用例。

我有一个按钮可以执行此操作。

  • 点击后,调用自定义 Controller 方法来更新模型和做其他事情
  • 调用 javascript 函数来更新页面而不重新加载它 (ajax)

现在,我能够调用自定义 Controller 方法的唯一方法是通过这种感觉非常笨拙的方法。我已将其简化为尽可能简单。

路线.rb

match 'admin/:id/toggleAdmin' => 'admin#toggleAdmin', via: [:patch, :put], as: :toggleAdmin

list.html.erb

<td><%= link_to "Toggle Admin", toggleAdmin_path(id: user.id), method: :patch %></td>

admin_controller.rb

class AdminController < ApplicationController

  def toggleAdmin
    idToToggle = User.find(params[:id]).id
    if idToToggle == current_user.id
      redirect_to admin_list_path, danger: "You tried to make yourself a normal user! Don't do that!"
    else
      User.find(params[:id]).updateToAdmin()
      redirect_to admin_list_path, info: "The user with an ID of #{idToToggle} has had their admin attribute toggled!"
    end
  end  

结束

我想做的不是在切换管理员时重新加载页面,而是使用一些 javascript 重写 dom 的那部分。

解决此问题的更好方法是什么?

这里只是我已经尝试过的各种资源中的一小部分。

感谢您的帮助。

--- 编辑以获取更多信息。

使用干净的 Rails 应用程序,我现在能够更干净地调用 Controller 方法,但我没有收到 ajax 请求来更新页面以显示操作已完成。 (我期待 bool 值变化和闪光灯)。以下是相关代码:

用户.js

$("#edit-form").html("<%= j render partial: 'form', locals: { user: @user } %>")

_form.html.erb

<%= form_for user do |form| %>
  <%= user.admin %>
<% end %>
<%= link_to "Toggle Admin", toggle_admin_user_path(user), method: :put, remote: true %>

编辑.html.erb

<h1>Editing User</h1>

<div id="edit-form">
  <%= render partial: 'form', locals: { user: @user } %>
</div>

<%= link_to 'Show', @user %> |
<%= link_to 'Back', users_path %>

users_controller.rb 请注意,我只包括了 toggle_admin和其他一些方法,其余的只是脚手架。

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy, :toggle_admin]

  def toggle_admin
    if 1 == 1
      logger.info "This is from info"
      u = User.find(params[:id])
      u.admin = !(u.admin)
      u.save
      respond_to do |format|
        format.js { flash[:info] = "The user with an ID of #{@user.id} has had their admin attribute toggled!" }
      end
    else
      redirect_to admin_list_path, danger: "You tried to make yourself a normal user! Don't do that!"
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_user
      @user = User.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def user_params
      params.fetch(:user, {})
    end
end

最佳答案

路由

首先,如果您需要资源中的嵌套自定义路由,您可以将其定义为该资源的成员:

resources :users do
  put 'toggle_admin', on: :member
end

返回:

toggle_admin    PUT    /users/:id/toggle(.:format)    users#toggle

其次,您的方法名称应该在 snake_case 中:def toggle_admin
See "Instance Methods" section

Controller

如果你只是想更新一个用户为管理员(通过这里的这个方法猜测:User.find(params[:id]).updateToAdmin()),你可以定义自定义的toggle_adminUsersController 中的方法。

你自定义的触发ajax请求的方法应该响应js格式并指向对应的js View (toggle_admin.js.erb)
作为资源 User 的成员,您可以将其添加到 before_action 回调中,以便在调用该方法时返回正确的用户。

class UsersController < ApplicationController
  before_action :set_user, only: [:show, :edit, :update, :destroy, :toggle_admin]
  #...
  def toggle_admin
    if #some condition
      # do some logic here
      respond_to do |format|
        format.js { flash[:info] = "The user with an ID of #{@user.id} has had their admin attribute toggled!" }
      end
    else
      redirect_to admin_list_path, danger: "You tried to make yourself a normal user! Don't do that!"
    end
  end
end

View

在rails views中,当你想使用ajax更新一个 View 而不用reload时,你需要使用partial。这是将在特定 DOM 元素上的 .js.erb 文件中刷新的部分。

让我们为用户#edit View 做一个例子。
首先,您需要在部分 form 中呈现 View ,并将其包装到具有特定 id 的 div 中:
edit.html.erb

<div id="edit-form">
  <%= render partial: 'form', locals: { user: @user } %>
</div>

局部:
_form.html.erb

<%= form_for user do |form| %>
  # the form
<% end %>
<%= link_to "Toggle Admin", toggle_admin_user_path(user), method: :put, remote: true %> 
# don't forget the remote: true for the ajax call

最后是自定义操作的 .js.erb(假设您有 jquery):
toggle_admin.js.erb

$("#edit-form").html("<%= j render partial: 'form', locals: { user: @user } %>")

瞧!单击链接时,您可以使用来自 Controller 的新信息刷新编辑 View ,而无需重新加载 View 。

当然,这是经典资源编辑 View 的示例,但您可以根据任何情况对其进行调整。只需在路由、 Controller 、 Controller 方法和 View (AdminController、 ListView 等...)之间保持良好的命名即可


编辑

要处理 flash 消息,您需要在布局中添加 > application.html.erb :

  <body>
    <% flash.each do |key, value| %>
      <%= content_tag :div, value, class: "classname" %>
    <% end %>
    <%= yield %>
  </body>

关于javascript - Rails AJAX 请求 Controller 方法,然后调用 javascript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50300962/

相关文章:

javascript - 触发点击具有 'download' 属性的链接

mysql - 为我的 Rails 应用添加数据库索引

jquery - rails 上的 ruby : submit a form clicking a check_box using JQuery

javascript - jQuery 自动完成的来源是隐藏输入变量的值

javascript - jquery noConflict 仅在 IE8 中不起作用

javascript - 将 @states 和 props 传递给弹出模型

javascript - 在 JS 客户端表单验证中联系服务器

javascript - 如何为不透明的 div 设置时间?

php - 将内容保存到 mysql 数据库时出现撇号 "'“问题

javascript - JS中对象变量改变事件如何处理 ||查询?