【问题标题】:Rails - removing li after destroying containing objectRails - 销毁包含对象后删除 li
【发布时间】:2015-06-19 07:54:04
【问题描述】:

我正在为一个完整的堆栈开发训练营计划构建一个项目应用程序。我正在实现一个从列表中删除给定项目的销毁方法。我正在实现一个 AJAX 请求,它应该从列表中删除项目的 li 。 destroy 方法正常工作,这意味着当我重新加载页面时元素消失了,但如果不重新加载页面就不会发生。

我的项目是通过部分渲染的:

<ul class="list-group">
  <% @list.items.each do |item| %>
    <!-- <li id="item-<%= @item.id %>" class="list-group-item"> -->
    <li class="list-group-item">
      <%= item.name %>
      <%= link_to "", [item.list, item], method: :delete, remote: true, class: 'glyphicon glyphicon-ok' %>
    </li> 
  <% end %>
</ul> 

我的 destroy.js.erb 文件:

<% if @item.destroyed? %>
  $('#item-' +<%= @item.id %>).hide();
  // $('#item-' +<%= @item.id %>).closest('li');
  // self.closest('li').remove();
  // $('li#item-<%= @item.id %>').hide();
  // $('#item-' +<%= @item.id %>).parent().remove();
  // $("li").remove('li#item-<%= @item.id %>');
<% else %>
  $('#item-' +<%= @item.id %>).prepend("<div class='alert alert-danger'><%= flash[:error] %></div>");
<% end %>

在我的 items_controller.rb 中:

def destroy
    @list = List.find(params[:list_id])
    @item = Item.find(params[:id])

    authorize @item

    if @item.destroy
      flash[:notice] = "Task Completed."
      # redirect_to @list
    else
      flash[:error] = "Task couldn't be deleted. Try again."
    end

    respond_to do |format|
      format.html
      format.js 
    end
  end

选择要删除的列表项时的终端输出:

Started DELETE "/lists/28/items/105" for ::1 at 2015-04-13 16:51:57 -0400
Processing by ItemsController#destroy as JS
  Parameters: {"list_id"=>"28", "id"=>"105"}
  List Load (0.1ms)  SELECT  "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT 1  [["id", 28]]
  Item Load (0.0ms)  SELECT  "items".* FROM "items" WHERE "items"."id" = ? LIMIT 1  [["id", 105]]
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ?  ORDER BY "users"."id" ASC LIMIT 1  [["id", 8]]
   (0.1ms)  begin transaction
  SQL (0.2ms)  DELETE FROM "items" WHERE "items"."id" = ?  [["id", 105]]
   (1.5ms)  commit transaction
  Rendered items/destroy.js.erb (0.6ms)
Completed 200 OK in 10ms (Views: 5.9ms | ActiveRecord: 2.0ms)

注释掉的行是我尝试删除元素的各种方法。非常感谢任何帮助。

【问题讨论】:

    标签: javascript jquery ruby-on-rails ajax


    【解决方案1】:

    当您输出li 时,您应该附上dom_id(@item),以便您以后可以引用它

    <li class="list-group-item" id="<%= dom_id(@item) %>">
    

    那你应该可以

    $("#<%= dom_id(@item) %>").remove();
    

    另外,这有点糟糕,因为您没有验证 @item 是否属于特定的 @list

    @list = List.find(params[:list_id])
    @item = Item.find(params[:id])
    

    这样更好

    @list = List.find(paramas[:list_id])
    @item = @list.items.find(params[:id])
    

    在此更改之前:

    DELETE /lists/1/items/2
    

    即使 Item#2 不属于 List#1 也可以工作。

    更改后:

    DELETE /lists/1/items/2
    

    除非项目#2 属于列表#1,否则不会工作

    【讨论】:

    • 当我尝试这个时,我在终端输出中得到了这个:Started DELETE "/lists/28/items/132" for ::1 at 2015-04-13 17:18:08 -0400 Processing by ItemsController#destroy as JS Parameters: {"list_id"=&gt;"28", "id"=&gt;"132"} List Load (0.1ms) SELECT "lists".* FROM "lists" WHERE "lists"."id" = ? LIMIT 1 [["id", 28]] Item Load (0.1ms) SELECT "items".* FROM "items" WHERE "items"."id" = ? LIMIT 1 [["id", 132]] Completed 404 Not Found in 2ms ActiveRecord::RecordNotFound (Couldn't find Item with 'id'=132): app/controllers/items_controller.rb:26:in destroy'`
    • 感谢您的方法建议!我的方法仍然适用于您的建议,所以我很高兴!
    • @naomik,我认为你的第一个请求应该是DELETE /items/2
    【解决方案2】:

    你可以使用这些 html 行

    <% @list.items.each do |item| %>
        <li id="item-<%= item.id %>" class="list-group-item">
        ....
    

    因此您对每个项目都有一个唯一的标识符。不知道你为什么把它注释掉了。

    然后在你的 destroy.js.erb 中执行此操作

    var item = $('li#item-' + <%= @item.id %>);
    item.hide();
    // or
    item.remove();
    

    您的控制器和服务器响应看起来不错。

    【讨论】:

    • 我把它注释掉了,因为出于某种原因它为每个 li 分配了相同的 id 号。
    • 对,因为它是 @item 而不是 item,尽管您在循环中。我已经编辑了答案。
    • 这非常有效!太感谢了!!!我会投票给你,但我的代表还不够高。 :-/
    猜你喜欢
    • 2012-05-31
    • 2014-01-22
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 2015-06-13
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    相关资源
    最近更新 更多