【问题标题】:using Ajax/jQuery for update action without page reload使用 Ajax/jQuery 进行更新操作,无需重新加载页面
【发布时间】:2016-10-21 19:16:05
【问题描述】:

我有一个 current_user 可以查看的个人资料页面,在该页面上会列出他们已回复的事件,并且在每个事件下方会有一个表格,如果他们愿意,可以将 RSVP 状态更新为不同的内容。这是他们可以从中选择的三种可能的 RSVP 状态的单选按钮(“参加”、“感兴趣”、“不感兴趣”)。我想让它在单击更新 RSVP 状态的单选按钮时不会重新加载页面。这是表单现在的样子。

  <% current_user.past_events.each do |event| %>
  <% rsvp_status = current_user.rsvp_for_event(event).status %>
    <% unless rsvp_status == "not_interested" %>
  <li><%= link_to event.title, event_path(event) %>
    <%= form_for ([current_user, current_user.rsvp_for_event(event)]), remote: true, html: { class: "update" } do |f| %>
                <%= f.hidden_field :event_id %>
      <%= f.radio_button :status, "attending", :onclick => "this.form.submit();" %>
                <%= f.radio_button :status, "interested", :onclick => "this.form.submit();"%>
      <%= f.radio_button :status, "not_interested", :onclick => "this.form.submit();" %>
    <% end %>

用户模型:

def rsvp_for_event(event)
  Rsvp.where(:event_id => event.id).first
end

更新

1) 我得到的错误是ActionController::UnknownFormat in RsvpsController#update

2) 表单的 HTML 类似于 &lt;form class="update" id="edit_rsvp_11" action="/users/1/rsvps/11" accept-charset="UTF-8" data-remote="true" method="post"&gt;,每个按钮的 HTML 类似于 &lt;input onclick="this.form.submit();" type="radio" value="attending" name="rsvp[status]" id="rsvp_status_attending"&gt;。我在 ).on('click 部分引用什么 - update 表单类,radio 按钮类型等?这里有经验法则吗?

3) URL 包含两个任意参数,user_idrsvp_id。如何在 AJAX 请求和 Rails 控制器的数据部分正确使用它们?

Rsvps控制器

  def update

    #is this part sufficient?
    respond_to do |format|
      format.html 
      format.js 
    end
  end

views/rsvps/update.js.erb,assets/javascripts 中应该有另一个文件吗?

$(document).on('ready', function() {
    //does the radio button reference go here?
    $('.radio').on('click', function(e) {
        e.preventDefault()

        $.ajax({
            type: 'POST',
            url: "users/" + user_id + "/rsvps/" + rsvp_id,
            data: {
                user_id: "<%= current_user.id %>"
                //in my view template, I added "<% rsvp_id = current_user.rspv_for_event(event)" 
                rsvp_id: "<%= rsvp_id %>"
            }
        }).done(function(response){ console.log('hello?', response)
        })
    })
})

【问题讨论】:

  • 不在你的 js 中......那个 ruby​​ 进入你的 html &lt;div class="some-class" data-user-id="&lt;%= current_user.id %&gt;"&gt; 然后在你的 js 中......你通过说 var user_id = $('.some-class').data('user-id') 得到那个 id 把它放在阻止默认值之后并执行得到rsvp_id 的同样的事情......不管那是什么......把它从页面上取下来。将这两个都传递给控制器​​动作。控制器操作的 url 应该是您添加到路由并在控制器中定义的新 url。不是演出路线。
  • 更新了我的答案,部分显示给你。

标签: jquery ruby-on-rails ajax


【解决方案1】:
  1. 是的,如果您希望它在 javascript 中响应而不重新加载页面,则需要 update.js.erb
  2. 为了指定您的表单在单击单选按钮时提交,您已经回答了自己的问题。您需要在单选按钮本身上添加一个点击监听器。

点击监听器

<script type="text/javascript">
  $('.radio-button-yes').on('click', function(e) {
    e.preventDefault() // Not necessary but here for precaution

    $.ajax... 
    // This is where you make your post to update action in controller
    // Make sure to specify type to be 'js'
  })

  // Repeat for the '.radio-button-no' class
</script>

update.js.erb

任何事情都可能发生在 javascript 中,所以我只举一个例子。

$(body).css({"backgroundColor":"pink"});

【讨论】:

  • 有什么经验法则吗?我是否应该使用包含按钮的表单部分中的某些内容,我有&lt;form class="update" id="edit_rsvp_11" action="/users/1/rsvps/11" accept-charset="UTF-8" data-remote="true" method="post"&gt;,所以类似于$('.edit_rsvp)...
  • 或者直接进入按钮元素,所以如果我有&lt;input onclick="this.form.submit();" type="radio" value="attending" name="rsvp[status]" id="rsvp_status_attending"&gt;,请执行$('.radio).on('click' etc之类的操作?
【解决方案2】:

您可以使用ajax:success 绑定。你只需要jquery-ujs gem。

我已经在这篇文章中解释了它的工作原理 Raise an alert/notice in rails controller WITHOUT redirect

因此,使用remote: true,rails 将使用 ajax 提交您的表单,然后您可以使用 ajax:something 绑定捕获返回并根据需要操作结果:)

【讨论】:

    【解决方案3】:

    你在使用 jQuery 吗?将单击事件绑定到您想要触发更新的任何元素。例如:

    在您的路线中:

    resources :users do
      collection do
        post "rsvp_to_event"
      end
    end
    

    在您的控制器中:

    def rsvp_to_event
      user_id = params[:user_id]
      rsvp_id = params[:rsvp_id]
    
      # do what you need to do
    
      # then render json and send back whatever you need
    
      render json: {data: "Success"}
    end
    

    在你看来:

    <button class="some-class" data-user-id="<%= current_user.id %>">Example</button>
    
    <script>
       $(document).on('ready', function(){
         $('.some-class').on('click', function(e){
         // this keeps page from reloading
         e.preventDefault()
    
         $.ajax({
           type: 'POST',
           url: '/controller_action_you_want_to_post_to',
           data: { user_id: $('.some-class').data('user-id') }
         }).done(function(response){ console.log('response', response })
         // you can update the page in the done callback
         // update your data in the controller action you're posting to
        }
       })
    </script>
    

    【讨论】:

    • 我的 rsvp_update 网址目前看起来像这样 /users/1/rsvps/11,取决于两个不断变化的独立 id(user_id 和 rsvp_id)。有什么好的方法来处理?
    • 将它们作为参数传递给 $.Ajax 请求中的数据对象。然后在控制器操作中获取它们两个 'params[:user_id]' 并在那里处理。
    • 我已经用我想出的东西更新了 OP,没有在网上找到任何 Rails + Ajax 示例。
    • 数据属性不应该是等号。 '用户 ID:'
    • 另外...是否定义了这些值?你需要用 JS 抓住它们
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    相关资源
    最近更新 更多