简体   繁体   English

如何从 javascript 中调用 Rails 方法

[英]How to call a Rails method from in javascript

I'm new in ruby on rails, I want to call controller method from javascript我是 ruby​​ on rails 的新手,我想从 javascript 调用控制器方法

show.html.erb显示.html.erb

<label class="switch">
  <%if @vehicle.parking%>
    <input type="checkbox" checked onchange="parkingMode(<%= @vehicle.id %>)">
  <%else%>
    <input type="checkbox" onchange="parkingMode(<%= @vehicle.id %>)">
  <%end%>
  <span></span>
</label>

vehicle_controller.rb车辆控制器.rb

def change_parking
  vehicle = Vehicle.find(params[:vehicle_id])
  if !vehiculo.parking
    vehicle.parking = true
    vehicle.save
  else
    vehicle.parking = false
    vehicle.save
  end
end

vehicle.js车辆.js

function parkingMode(id){
    console.log(id)
}

You can't call a Rails controller method directly from within the view, you need to send a request to it.您不能直接从视图中调用 Rails 控制器方法,您需要向它发送请求。

A good way to do this is with a form:一个很好的方法是使用表单:

<%= form_for(@vehicle) do |f| %>
  <input name="parked" type="checkbox" checked="<%=@vehicle.parked%>" />
  <input type="submit" />
<%= end %>

Then your controller could update the vehicle depending on whether params[:parked] is checked and redirect back to the same page然后您的控制器可以根据是否检查params[:parked]并重定向回同一页面来更新车辆

def change_parked
  @vehicle.update_column(:parked, params[:parked])
  redirect_to vehicle_path(@vehicle.id)
end

The benefit of this is that you don't need any JavaScript to make changes to the vehicle.这样做的好处是您不需要任何 JavaScript 来更改车辆。 However, if you want to avoid a page refresh...但是,如果您想避免页面刷新...

To do this without a form, you will need to use JavaScript and Ajax to ping the endpoint that routes to that controller method.要在没有表单的情况下执行此操作,您需要使用 JavaScript 和 Ajax 来 ping 路由到该控制器方法的端点。

So, your parkingMode JavaScript method could be something like (I'm using jQuery for ease here)因此,您的parkingMode JavaScript 方法可能类似于(我在这里使用jQuery 以方便)

const request = $.post('/vehicles/change_parking')
request.done((response) => {
  console.log('Do something here')
})

This would call your controller method, which could return JSON as a result:这将调用您的控制器方法,结果可能会返回JSON

def change_parking
  vehicle = Vehicle.find(params[:vehicle_id])
  if !vehiculo.parking
    vehicle.parking = true
    vehicle.save
  else
    vehicle.parking = false
    vehicle.save
  end

  render json: { vehicle: vehicle }, status: 200
end

Then you would need to change the checked value of the checkbox:然后您需要更改复选框的checked值:

const request = $.post('/vehicles/change_parking')
request.done((response) => {
  $('input[type="checkbox"]).attr('checked', response.responseJSON.vehicle.parked)
})

There's a couple of things I want to address.有几件事我想说明一下。

Firstly, you're using an if statement in your view when you could simplify it to something like:首先,当您可以将其简化为以下内容时,您在视图中使用了if语句:

<input type="checkbox" checked="<%= @vehicle.parked %> onchange="parkingMode(<%= @vehicle.id %>)">

This means that the checkbox will only be checked if the vehicle is parked.这意味着只有在车辆停放时才会checked该复选框。

Secondly, in your change_parking method, you only need to call save once其次,在您的change_parking方法中,您只需要调用一次save

def change_parking
  vehicle = Vehicle.find(params[:vehicle_id])
  if !vehiculo.parking
    vehicle.parking = true
  else
    vehicle.parking = false
  end

  vehicle.save
end

You could also do something like vehicle.parking = !vehicle.parking and remove the if statement.您还可以执行类似vehicle.parking = !vehicle.parking并删除if语句。

You can call a controller action using JS.可以使用 JS 调用控制器操作。 But not directly.但不是直接的。 However, you can use the tools already provided by Rails to do so.但是,您可以使用 Rails 已经提供的工具来执行此操作。

First, we render a remote checkbox:首先,我们渲染一个远程复选框:

check_box_field 'parking_mode_toggle', '1', false, remote: true, data: { url: '/change_parking' }

Even though it's not given in the official document , if you read the Rails UJS code , you'll see that the UJS driver will make the request as soon as the checkbox is ticked/un-ticked.即使官方文档中没有给出,但如果您阅读Rails UJS 代码,您会看到只要勾选/取消勾选复选框,UJS 驱动程序就会发出请求。

Then, in your controller, you can do:然后,在您的控制器中,您可以执行以下操作:

def change_parking
  # TODO: Change your database state according to the +params+ received

  respond_to do |format|
    format.js { render js: 'parkingMode()' }
  end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM