【问题标题】:Delete / Destroy is not working in rails 3 with jQuery删除/销毁在带有 jQ​​uery 的 rails 3 中不起作用
【发布时间】:2011-04-16 15:00:36
【问题描述】:

我的删除/销毁不适用于 Rails 3。

不适用于任何脚手架,甚至不适用于新项目。

<%= link_to 'Destroy', card, :confirm => 'Are you sure?', :method => :delete %> 

来自this question。解决方法是重新安装火狐。但我的也不能在 chrome、safari 或 opera 中工作。

生成的HTML代码:--

 <a href="/categories/1" data-confirm="Are you sure?" data-method="delete" rel="nofollow">Destroy</a>

PS:请不要说包含默认的 JS 文件什么的。因为我对原型不感兴趣,因为我正在使用 jQuery。

编辑/更新,重要提示:这是您根本不想使用原型时的解决方案。我在我的项目中只使用 jQuery 和相应的插件。

人们正在回答:首先包含原型等,然后安装一些gem等以消除原型和jQuery之间的冲突。那是垃圾。

我已经发布了答案。请在选择该选项之前检查一次。为我工作了 10 多个项目,没有任何问题。您需要做的就是:

从您的 javascript 目录中删除除 application.js 之外的所有 js 文件。然后将我在答案中指定的代码粘贴到一个新文件中并包含该文件。包括 Jquery.js,然后一切就绪。您无需添加默认 javascript(即:原型)或其他一些 gem 来消除冲突等。

【问题讨论】:

    标签: jquery ruby-on-rails-3 destroy


    【解决方案1】:

    我遇到了 Mohit 遇到的同样问题,还需要在我的 JavaScript 资产中包含“Unobtrusive JavaScript Library”(或“ujs”)。在我当前的 Rails (v3.2.5) 中,将自动提供 UJS 库。您可以通过查看 Gemfile 中的以下行来验证这一点:

    gem 'jquery-rails'

    以及您的 app/assets/javascripts/application.js 文件中的以下行:

    //= require jquery_ujs

    由于我没有更好的了解,我从自己的 application.js 文件中删除了 require jquery_ujs 行,我花了一段时间才弄清楚为什么我的 link_to ..., :method =&gt; :delete 调用不再工作了!

    一旦我理解了问题所在,就很容易将上述两行添加回各自的文件中,一切又开始按预期工作了。

    【讨论】:

      【解决方案2】:

      如果您使用 jQuery 而不是 Prototype,那么您需要在项目中添加 Jquery.rails.js,否则每次您尝试删除任何内容时都会显示页面。

      我不记得我从哪里得到解决方案和这个 Jquery.rails.js 文件。但肯定来自一些值得信赖的来源。

      这是该文件的代码:

      jQuery(function ($) {
          var csrf_token = $('meta[name=csrf-token]').attr('content'),
              csrf_param = $('meta[name=csrf-param]').attr('content');
      
          $.fn.extend({
              /**
               * Triggers a custom event on an element and returns the event result
               * this is used to get around not being able to ensure callbacks are placed
               * at the end of the chain.
               *
               * TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our
               *       own events and placing ourselves at the end of the chain.
               */
              triggerAndReturn: function (name, data) {
                  var event = new $.Event(name);
                  this.trigger(event, data);
      
                  return event.result !== false;
              },
      
              /**
               * Handles execution of remote calls firing overridable events along the way
               */
              callRemote: function () {
                  var el      = this,
                      data    = el.is('form') ? el.serializeArray() : [],
                      method  = el.attr('method') || el.attr('data-method') || 'GET',
                      url     = el.attr('action') || el.attr('href');
      
                  if (url === undefined) {
                    throw "No URL specified for remote call (action or href must be present).";
                  } else {
                      if (el.triggerAndReturn('ajax:before')) {
                          $.ajax({
                              url: url,
                              data: data,
                              dataType: 'script',
                              type: method.toUpperCase(),
                              beforeSend: function (xhr) {
                                  el.trigger('ajax:loading', xhr);
                              },
                              success: function (data, status, xhr) {
                                  el.trigger('ajax:success', [data, status, xhr]);
                              },
                              complete: function (xhr) {
                                  el.trigger('ajax:complete', xhr);
                              },
                              error: function (xhr, status, error) {
                                  el.trigger('ajax:failure', [xhr, status, error]);
                              }
                          });
                      }
      
                      el.trigger('ajax:after');
                  }
              }
          });
      
          /**
           *  confirmation handler
           */
          $('a[data-confirm],input[data-confirm]').live('click', function () {
              var el = $(this);
              if (el.triggerAndReturn('confirm')) {
                  if (!confirm(el.attr('data-confirm'))) {
                      return false;
                  }
              }
          });
      
      
          /**
           * remote handlers
           */
          $('form[data-remote]').live('submit', function (e) {
              $(this).callRemote();
              e.preventDefault();
          });
          $('a[data-remote],input[data-remote]').live('click', function (e) {
              $(this).callRemote();
              e.preventDefault();
          });
      
          $('a[data-method]:not([data-remote])').live('click', function (e){
              var link = $(this),
                  href = link.attr('href'),
                  method = link.attr('data-method'),
                  form = $('<form method="post" action="'+href+'">'),
                  metadata_input = '<input name="_method" value="'+method+'" type="hidden" />';
      
              if (csrf_param != null && csrf_token != null) {
                metadata_input += '<input name="'+csrf_param+'" value="'+csrf_token+'" type="hidden" />';
              }
      
              form.hide()
                  .append(metadata_input)
                  .appendTo('body');
      
              e.preventDefault();
              form.submit();
          });
      
          /**
           * disable-with handlers
           */
          var disable_with_input_selector = 'input[data-disable-with]';
          var disable_with_form_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')';
      
          $(disable_with_form_selector).live('ajax:before', function () {
              $(this).find(disable_with_input_selector).each(function () {
                  var input = $(this);
                  input.data('enable-with', input.val())
                       .attr('value', input.attr('data-disable-with'))
                       .attr('disabled', 'disabled');
              });
          });
      
          $(disable_with_form_selector).live('ajax:after', function () {
              $(this).find(disable_with_input_selector).each(function () {
                  var input = $(this);
                  input.removeAttr('disabled')
                       .val(input.data('enable-with'));
              });
          });
      });
      

      更新

      您可以从这里获取 Jquery.rails.js 的最新副本。

         https://raw.github.com/rails/jquery-ujs/master/src/rails.js
      

      【讨论】:

      • 如果您使用资产管道,这不是最好的方法。如果您使用资产管道,Justin Houk 的答案会更好。
      • @Justin houk 的答案更好,我不明白为什么这个答案比他的投票高。无论如何,谢谢你 Mab879,你节省了我的时间,也谢谢贾斯汀胡克
      • @edisonthk 导致我发布此答案的时间。 Jquery-rails gem 没有发布。我现在已经改变了接受的答案..
      • 我可以理解,保持更新不是一件容易的事情......无论如何,快乐编码
      【解决方案3】:

      确保在布局中包含默认的 Rails javascript 文件。

      <%= javascript_include_tag :defaults %>
      

      【讨论】:

      • 当我使用 Jquery 时,我为什么要这样做。仍然出于测试目的,我这样做了。仍然没有工作。
      • Rails 3 使用不显眼的 javascript 使其工作。所以你必须包含一些 javascript 框架(Prototype 或 JQuery)和适当的rails.js。请参阅the screencast by Ryan Bates 了解更多信息。
      • 如果您使用 jquery-rails 而不是原型-rails gem(默认情况下),您应该在此处获取 jquery javascripts。此答案仅适用于 Rails 3.0。
      【解决方案4】:

      确保在布局中包含默认的 Rails javascript 文件。

      <%= javascript_include_tag "application" %>
      

      【讨论】:

      • application.js 是一个空白的 js 文件:P 检查我的答案。
      猜你喜欢
      • 2011-04-10
      • 2022-06-13
      • 2011-05-13
      • 2018-02-24
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多