【问题标题】:How can I override Rails 3 unobtrusive javascript functions without modifying the supplied rails.js?如何在不修改提供的 rails.js 的情况下覆盖 Rails 3 不显眼的 javascript 函数?
【发布时间】:2011-07-18 23:36:21
【问题描述】:

我的 Javascript 还不够完善,我正在努力重写提供的 rails.js 中的一个函数。

我想修改 a[data-confirm] 的处理方式,使用 jQuery UI 模式对话而不是原版 javascript confirm()

rails.js中的相关函数为allowAction(element)。如果我在另一个文件中定义它,我可以从 firebug 控制台成功调用它,但 rails.js 版本仍然是从具有 data-confirm 属性的锚点调用的。

我认为这是因为整个 rails.js 文件被包裹在:

(function($) {
...
})( jQuery );

有没有一种明智的方法来覆盖这个函数,不修改提供的rails.js

编辑:

rails.jsallowAction 的调用被封装在 .live 调用中:

  $('a[data-confirm], a[data-method], a[data-remote]').live('click.rails', function(e) {
  var link = $(this);
  if (!allowAction(link)) return false;

  if (link.attr('data-remote')) {
    handleRemote(link);
    return false;
  } else if (link.attr('data-method')) {
    handleMethod(link);
    return false;
  }   
});

我还尝试在 rails.js 之前和之后包含我的 javascript,但无济于事。

编辑:

所以,如果我调用 .die('click.rails'),我可以重新定义整个 click.rails 事件,但不会调用原始的 handleRemote()handleMethod() 函数。

【问题讨论】:

    标签: jquery ruby-on-rails-3 overriding unobtrusive-javascript


    【解决方案1】:

    像这样?

    //Backup our original function just in case
    var backupFunc = allowAction;
    
    //Your replacement function
    var myFunc = function(element){
        //Have it your way, badabababa :)
    };
    
    //Override default 'allowAction' function
    
    allowAction = myFunc;
    
    /*
        Restore it the way it was before: allowAction = backupFunc;
    */
    

    编辑: 函数的作用域是封闭作用域。因此,您将无法按照自己的意愿对它们采取行动。

    【讨论】:

    • 不走运,这与我尝试的行为相同。更新了更多信息的问题
    • 如果你在重新定义click.rails事件,那你就不能像原来那样让handleRemote()和handleMethod()被调用吗?跨度>
    • 这就是我所做的 - 复制并粘贴整个 .live 匿名函数,并将 allowAction 调用替换为 myAllowAction。当我尝试在复制的代码中调用 handleRemotehandleMethod 函数时,它们未定义。
    • 我不确定 Ruby 是如何工作的(我从未使用过它)。所以我不确定我能在这里提供更多帮助,但我不认为你能做到这一点。加上范围是封闭的。
    • 您能否详细说明“范围已关闭”?它应该是独立于 Rails 的——它实际上只是 JS,但我将它标记为 rails,以防使用该库的任何人之前解决过这个问题。谢谢:)
    【解决方案2】:

    我刚刚检查了rails.js 代码(我使用的是Rails 3.0.3 和jquery-rails 0.2.7),它调用confirm() 方法的点与你的不同。我的看起来更容易更换:

    function allowAction(element) {
        var message = element.data('confirm');
        return !message || (fire(element, 'confirm') && confirm(message));
    }
    

    也许您可以升级您的jquery-rails gem(并重新运行rails generate jquery:install)?

    【讨论】:

    • 确认一下,您的allowAction 功能与我的rails.js 相同。我复制粘贴的代码是点击链接时调用allowAction函数的事件处理程序。
    【解决方案3】:

    仅供参考,我刚刚为 Rails jquery-ujs 添加了一个外部 API 来完成这类事情。您现在可以通过插入(并重写 1 行)$.rails.allowAction 函数使 rails.js 使用自定义确认方法。

    请参阅我的文章Rails jQuery UJS: Now Interactive,以获取完整的示例说明。

    编辑:现在,从this commit 开始,confirm 对话框函数可以以同样的方式被覆盖。例如

    $.rails.confirm = function(message) { return myConfirmDialog(message); };
    

    【讨论】:

    • 更好的是,我刚刚将confirm 对话框移动到$.rails 对象,因此使用其他一些确认对话框更加容易。查看更新的答案。
    • 我想知道您将如何访问触发确认的元素,以便您可以基于此自定义对话框?
    猜你喜欢
    • 1970-01-01
    • 2011-03-31
    • 2011-06-12
    • 2017-02-04
    • 2019-02-06
    • 2013-04-18
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    相关资源
    最近更新 更多