Rails 4:切换 link_to 与 Ajax 和 jQuery(嵌套资源)
Rails 4: Toggle link_to with Ajax and jQuery (nested resources)
我在 'ideas' 上有 'complete' 和 'incomplete' 链接。我想在不重新加载页面的情况下切换它们。
这是我当前的代码:
_idea.html.erb 部分:
<li id="<%= dom_id(idea) %>">
<%= idea.description %>
<% if idea.completed? %>
<%= link_to "Incomplete", complete_project_idea_path(idea.project, idea), method: :patch, remote: true %>
<% else %>
<%= link_to "Complete", complete_project_idea_path(idea.project, idea), method: :patch, remote: true %>
<% end %>
</li>
这是我的控制器操作(我使用的是嵌套资源):
def complete
@project = Project.find(params[:project_id])
@idea = @project.ideas.find(params[:id])
respond_to do |format|
@idea.toggle_completion!
format.html {redirect_to root_path}
format.js { }
end
end
并且在 idea.rb 模型中:
def completed?
!completed_at.blank?
end
def toggle_completion!
if completed?
update_attribute(:completed_at, nil)
else
update_attribute(:completed_at, Time.now)
end
end
Complete.js.erb 文件;
$('#<%= dom_id(@idea)%>').html("What here? How can I toggle between the complete and incomplete links?");
我也尝试将 link_to 放入新的偏音中,但这变得太复杂了(因为它们是子偏音)并且也没有用。
我应该在 complete.js.erb 文件中尝试什么?
编辑:谢谢@Fer!我做了以下更改,但它还没有完全起作用。
我将 complete.js.erb 更改为:
$("#toggle_completion_link").text("<%= @idea.completed? ? 'Incomplete' : 'Complete' %>")
我将想法更改为@idea,因为没有它我得到了'undefined local variable or method `idea''错误。
同样在_idea.html.erb部分,在projects/idea.html.erb下,我改为:
<%= link_to (idea.completed? ? 'Incomplete' : 'Complete'), complete_project_idea_path(idea.project, idea), method: :patch, remote: true, id: 'toggle_completion_link' %>
但它还没有正常工作,尽管我确实收到了 'completed 200 ok' 消息。
Started PATCH "/projects/1/ideas/4/complete" for ...
Processing by IdeasController#complete as JS
Parameters: {"project_id"=>"1", "id"=>"4"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Project Load (0.2ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = LIMIT 1 [["id", 1]]
Idea Load (0.2ms) SELECT "ideas".* FROM "ideas" WHERE "ideas"."project_id" = AND "ideas"."id" = ORDER BY priority ASC LIMIT 1 [["project_id", 1], ["id", 4]]
Rendered ideas/complete.js.erb (0.5ms)
Completed 200 OK in 9ms (Views: 3.3ms | ActiveRecord: 1.8ms)
好吧,在您的情况下,您只需要更改 link 文本,因为两个 link 都指向相同的 url 和方法。
我会像在 _idea.html.erb
中那样干掉它
<li id="<%= dom_id(idea) %>">
<%= idea.description %>
<%= link_to (idea.completed? ? 'Incomplete' : 'Complete'), complete_project_idea_path(idea.project, idea), method: :patch, remote: true, id: 'toggle_completion_link' %>
</li>
注意最后 link 的 id
属性。
如果您要显示多个项目并且您有 ID 问题,我会使用 dom_id(idea)
作为 link(或类似 dom_id(idea) + '_link'
的变体)的 ID,而不是包含它的 li
。
然后,作为您 ajax 请求的答复,在您的 complete.js.erb
文件中:
$("#toggle_completion_link").text("<%= idea.completed? ? 'Incomplete' : 'Complete' %>")
你也可以替换整个东西,但我不明白这里的意义,因为你只需要切换 link 文本。无论如何,对于教学,您可以像下面这样渲染整个部分:
$("#<%= dom_id(idea) %>").replace("<%= escape_javascript(render 'idea', object: @idea %>")
您可能需要调整部分路径,因为您没有说明它位于何处
我在 'ideas' 上有 'complete' 和 'incomplete' 链接。我想在不重新加载页面的情况下切换它们。
这是我当前的代码:
_idea.html.erb 部分:
<li id="<%= dom_id(idea) %>">
<%= idea.description %>
<% if idea.completed? %>
<%= link_to "Incomplete", complete_project_idea_path(idea.project, idea), method: :patch, remote: true %>
<% else %>
<%= link_to "Complete", complete_project_idea_path(idea.project, idea), method: :patch, remote: true %>
<% end %>
</li>
这是我的控制器操作(我使用的是嵌套资源):
def complete
@project = Project.find(params[:project_id])
@idea = @project.ideas.find(params[:id])
respond_to do |format|
@idea.toggle_completion!
format.html {redirect_to root_path}
format.js { }
end
end
并且在 idea.rb 模型中:
def completed?
!completed_at.blank?
end
def toggle_completion!
if completed?
update_attribute(:completed_at, nil)
else
update_attribute(:completed_at, Time.now)
end
end
Complete.js.erb 文件;
$('#<%= dom_id(@idea)%>').html("What here? How can I toggle between the complete and incomplete links?");
我也尝试将 link_to 放入新的偏音中,但这变得太复杂了(因为它们是子偏音)并且也没有用。
我应该在 complete.js.erb 文件中尝试什么?
编辑:谢谢@Fer!我做了以下更改,但它还没有完全起作用。
我将 complete.js.erb 更改为:
$("#toggle_completion_link").text("<%= @idea.completed? ? 'Incomplete' : 'Complete' %>")
我将想法更改为@idea,因为没有它我得到了'undefined local variable or method `idea''错误。
同样在_idea.html.erb部分,在projects/idea.html.erb下,我改为:
<%= link_to (idea.completed? ? 'Incomplete' : 'Complete'), complete_project_idea_path(idea.project, idea), method: :patch, remote: true, id: 'toggle_completion_link' %>
但它还没有正常工作,尽管我确实收到了 'completed 200 ok' 消息。
Started PATCH "/projects/1/ideas/4/complete" for ...
Processing by IdeasController#complete as JS
Parameters: {"project_id"=>"1", "id"=>"4"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ORDER BY "users"."id" ASC LIMIT 1 [["id", 1]]
Project Load (0.2ms) SELECT "projects".* FROM "projects" WHERE "projects"."id" = LIMIT 1 [["id", 1]]
Idea Load (0.2ms) SELECT "ideas".* FROM "ideas" WHERE "ideas"."project_id" = AND "ideas"."id" = ORDER BY priority ASC LIMIT 1 [["project_id", 1], ["id", 4]]
Rendered ideas/complete.js.erb (0.5ms)
Completed 200 OK in 9ms (Views: 3.3ms | ActiveRecord: 1.8ms)
好吧,在您的情况下,您只需要更改 link 文本,因为两个 link 都指向相同的 url 和方法。
我会像在 _idea.html.erb
<li id="<%= dom_id(idea) %>">
<%= idea.description %>
<%= link_to (idea.completed? ? 'Incomplete' : 'Complete'), complete_project_idea_path(idea.project, idea), method: :patch, remote: true, id: 'toggle_completion_link' %>
</li>
注意最后 link 的 id
属性。
如果您要显示多个项目并且您有 ID 问题,我会使用 dom_id(idea)
作为 link(或类似 dom_id(idea) + '_link'
的变体)的 ID,而不是包含它的 li
。
然后,作为您 ajax 请求的答复,在您的 complete.js.erb
文件中:
$("#toggle_completion_link").text("<%= idea.completed? ? 'Incomplete' : 'Complete' %>")
你也可以替换整个东西,但我不明白这里的意义,因为你只需要切换 link 文本。无论如何,对于教学,您可以像下面这样渲染整个部分:
$("#<%= dom_id(idea) %>").replace("<%= escape_javascript(render 'idea', object: @idea %>")
您可能需要调整部分路径,因为您没有说明它位于何处