Rails 3 Ajax-JQuery: 销毁对象时视图未更新

Rails 3 Ajax-JQuery: view not updated when destroying an object

我在使用 Rails 3.2.11.

销毁 AJAX 中的对象时遇到问题

我遵循了这个教程: http://www.tutorialspoint.com/ruby-on-rails/rails-and-ajax.htm

控制器工作正常,但在视图中,没有做任何正确的事情。我认为我的问题是 JQuery,但我不确定,所以我的问题在哪里?

//views/tournaments/index.html.haml
%table.table.table-hover.table-bordered
 %thead
  %th Name
  %th Place
  %th Nb players max
  %th
  - if can? :update, @tournaments
   %th
  - if can? :destroy, @tournaments
   %th
 - @tournaments.each do |tournament|
  %tr
   %td= tournament.name
   %td= tournament.place
   %td= tournament.nb_players_max
   %td= link_to 'Show', tournament
   - if can? :update, @tournaments
    %td= link_to 'Edit', edit_tournament_path(tournament)
   - if can? :destroy, @tournaments
    %td= link_to 'Destroy', tournament, method: :delete, data: {confirm: 'Are you sure?'}, :class => 'delete', :remote => true

我的控制器tournaments_controller.rb:

 def destroy
  @tournament = Tournament.find(params[:id])
  @tournament.destroy

  respond_to do |format|
   format.html { redirect_to tournaments_url }
   format.json { head :no_content }
   format.js   { render :layout => false }
  end
 end

destroy.js.erb:

console.log("hello");
$('.delete').bind('ajax:success', function(){
 console.log("delete!");
 $(this).parent('tr').fadeOut(400, function(){
  $(this).remove();
 });
});

控制台告诉我控制器工作正常(200 OK),控制台显示 Hello 但没有其他...

发生了什么事? :-(

编辑:

我做了一个测试,专门创建了一个项目来测试这个教程,它运行良好。但不是在我上面的项目中:(

编辑@DickieBoy: 我试过了,但没用:

$(document).ready(function(){
 $('.delete').bind('ajax:success', function() {
  console.log("delete!");
  $(this).closest('tr').fadeOut(400, function () {
   $(this).remove();
  });
 });
});

我怀疑问题是 ajax:success 事件在任何 'delete' class 存在之前绑定到 'delete' class。因此:

$(document).ready(function(){
  $('.delete').bind('ajax:success', function(){
    console.log("delete!");
    $(this).parent('tr').fadeOut(400, function(){
    $(this).remove();
  });
});

应该修复它。

我建议further reading on jquery events


编辑:

问题不在于事件的加载。是随着parent的调用。

来自 jQuery 文档:

This method is similar to .parents(), except .parent() only travels a single level up the DOM tree.

所以 $(this).parent('tr') returns 一个空数组,因为父数组不是 tr.

使用这个:

$('.delete').bind('ajax:success', function(){
  console.log("delete!");
  $(this).parents('tr').fadeOut(400, function(){ // this line has changed
    $(this).remove();
  });
});

解决方法在这里!

当你打电话时

:remote => true

它在控制器中执行操作,然后 destroy.js.erb。

文档已经准备好了,使用JQuery,这个很简单。为此,我们只需要做:

$('#del-<%= @tournament.id %>').closest('tr').fadeOut(400, function () {
 $(this).remove();
});

@tournament.id???它来自这里,在我看来:

%td= link_to 'Destroy', tournament, method: :delete, data: {confirm: 'Are you sure?'}, :id => "del-#{tournament.id}", :remote => true

一切正常! ;-)

编辑:

You also have the problem of passing the id of the tournament into the javascript so you will have a unique piece of javascript for every tournament that is on the index page. I must have missed something, on 'delete' being logged. What event triggers the current code? – DickieBoy 21 hours ago

remote: true turns the elements action into an ajax call. So either ajax:success was running or the call wasn't working. – DickieBoy 20 hours ago

拿到锦标赛ID没问题。首先,我的观点有这个元素:

  %td= link_to 'Destroy', tournament, method: :delete, data: {confirm: 'Are you sure?'}, :id => "del-#{tournament.id}", :remote => true, :class => 'btn btn-danger btn-sm'

当我点击它时,这个调用 AJAX(你是对的!)。但在此之前,它会在我的控制器中执行操作:

def destroy
  # @tournament is finded in a before_filter (or before_action for those using Rails 4)
  @tournament.destroy

  respond_to do |format|
    format.html { redirect_to tournaments_url }
    format.json { head :no_content }
    format.js
    # thanks to this, I can call my destroy.js.erb
  end
 

因为销毁操作成功,它调用 destroy.js.erb:

$('#del-<%= @tournament.id %>').closest('tr').fadeOut(400, function () {
 $(this).remove();
});
 

closest works here because of the specification of html tables, you should be using parents, it more accurately describes what is happening. – DickieBoy 20 hours ago

关于 'closest',我认为这是比 'parents' 更好的答案。它似乎更快。看这里:http://www.sitepoint.com/jquerys-closest-parents/

我希望我理解你的问题并正确回答了它们:-) 我愿意接受建议:-)

PS:我可能忘了告诉你我正在使用 JQuery UJS。这是我的 application.js:

//= require jquery
//= require jquery_ujs
//= require bootstrap
//= require_tree .