我有以下代码:
<% @jobs.each do |job| %>
<tr>
<td>
<div class="job"><%= link_to(job.title, job.url, :target => "_blank") %>
<a id="add-to-favorites"><i class="fa fa-heart" title="Save to my jobs"></i></a></div>
...
def add_to_favorites
//I would like to see some params here also
puts "made it to add_to_favorites"
end
$("#add-to-favorites").click(function(){
$.ajax({url: "add_to_favorites",
type: "GET",
data: {}
});
});
get 'add_to_favorites', to: 'jobs#add_to_favorites'
两个问题。首先,如何获得每个作业的点击/ ajax调用。现在,它仅适用于页面上的第一个作业。我猜这是由于我对视图中的每个作业都使用了id="add-to-favorites"
。这是每个工作的唯一ID吗?
第二,如何将参数传递给控制器?
答案 0 :(得分:1)
您对ID的担心是正确的。您可能应该在元素上包含具有id属性的对象id。您可以执行以下操作:
<%= link_to '#', id: "add-to-favorites-#{job.id}" do %>
<i class="fa fa-heart" title="Save to my jobs"></i>
<% end %>
...但是这将使得很难通过JavaScript进行定位。您最好这样做:
<%= link_to '#', id: "add-to-favorites-#{job.id}", class: 'some-class', data: {id: job.id} do %>
<i class="fa fa-heart" title="Save to my jobs"></i>
<% end %>
这样,您可以使用data-id
属性获取所需的ID。
$(".some-class").click(function(e){
e.preventDefault();
var idToGet = $(this).data('id');
data = {
id: idToGet,
// whatever else you need to pass to your controller as params
};
$.ajax({
url: "add_to_favorites",
type: "GET",
data: data
});
});
您以data
身份通过的所有内容都应以params
身份出现在您的控制器中。同样,通常将这类事情配置为使用POST
请求。
答案 1 :(得分:1)
这是每个工作的唯一ID吗?
是的。根据定义,页面上只有给定id
的一个元素。我想我会做更多的事情:
<% @jobs.each do |job| %>
<tr>
<td>
<div class="job">
<%= link_to(job.title, job.url, :target => "_blank") %>
<i class="fa fa-heart add-to-favorites-icon" data-id="<%= job.id %>" title="Save to my jobs"></i>
</div>
...
自从我使用erb
已经很久了,所以您可能需要弄弄它来正确设置data-id
。我已删除了a
元素,因为它似乎不是必需的。
然后,我想我将您的routes.rb
更改为更像:
resources :jobs do
member do
post :add_to_favorites
end
end
我认为使用POST
HTTP动词执行此操作更为常规,因为它不是幂等的。这将为您提供:
add_to_favorites_job POST /jobs/:id/add_to_favorites(.:format) jobs#add_to_favorites
jobs GET /jobs(.:format) jobs#index
POST /jobs(.:format) jobs#create
new_job GET /jobs/new(.:format) jobs#new
edit_job GET /jobs/:id/edit(.:format) jobs#edit
job GET /jobs/:id(.:format) jobs#show
PATCH /jobs/:id(.:format) jobs#update
PUT /jobs/:id(.:format) jobs#update
DELETE /jobs/:id(.:format) jobs#destroy
然后,我将您的js
更改为更像:
$(".add-to-favorites-icon").click(function(){
$.ajax({
url: "jobs/#{$(this).data().id}/add_to_favorites",
type: "POST",
data: {}
});
});
您可能需要摆弄一下。
$(this)
将引用所单击的图标,而$(this).data().id
应返回上面设置的id
。字符串插值可为您提供一个类似于jobs/1/add_to_favorites
的网址(或任何id
是)。然后,单击该图标将进行POST调用,该调用将通过add_to_favorites
参数路由到您的id
操作,您可以使用它来查找job
。
如何将参数传递给控制器?
要将参数传递给控制器,请在data
调用中使用$.ajax
参数。像这样:
$(".add-to-favorites-icon").click(function(){
$.ajax({
url: "jobs/#{$(this).data().id}/add_to_favorites",
type: "POST",
data: {
foo: 'bar'
}
});
});
这将进行POST调用,该调用将通过add_to_favorites
参数和id
参数路由到您的foo
操作。
现在,在我看来,您可能希望将喜欢的图标用作拨动开关。也就是说,如果某人尚未收藏该工作,则单击该图标会将其添加为收藏。并且,如果某人喜欢该工作,则单击该工作将使该工作不受欢迎。因此,您可以执行以下操作:
<% @jobs.each do |job| %>
<tr>
<td>
<div class="job">
<%= link_to(job.title, job.url, :target => "_blank") %>
<i class="fa fa-heart <%= current_user.favorited_jobs.include?(job) ? 'favorited' : 'not-favorited' %>" data-id="<%= job.id %>" title="Save to my jobs"></i>
</div>
...
(自然地,您假设您可以做类似current_user.favorited_jobs.include?(job)
的事情,您可能必须创建它。这只是一个示例。)
然后,您可以使用“收藏”和“未收藏”类来更改css
中的图标颜色,以便用户获得有关他们已收藏的内容的视觉反馈。
然后将routes.rb
更改为:
resources :jobs do
member do
post :add_to_favorites
post :remove_from_favorites
end
end
然后将您的js
更改为以下内容:
$(".job .not-favorited").click(function(){
$.ajax({
url: "jobs/#{$(this).data().id}/add_to_favorites",
type: "POST",
data: {}
})
.done(function(){
$(this).removeClass('not-favorited').addClass('favorited')
});
});
$(".job .favorited").click(function(){
$.ajax({
url: "jobs/#{$(this).data().id}/remove_from_favorites",
type: "POST",
data: {}
})
.done(function(){
$(this).removeClass('favorited').addClass('not-favorited')
});
});
现在,单击图标既可以更改模型中的收藏状态,也可以更改前端的图标颜色(假设您已经用css
了)。