2010-02-04 59 views
0

我正在使用Rails和jQuery,通过单击链接发起ajax调用。我设置我的application.js文件看起来像提议here,它很好。我遇到的问题是如何在我的say.update.js.erb文件中使用$(this)来表示我单击的链接?我不希望有一个ID分配给每个人,然后重新编译回调脚本ID ..

编辑 举的类似一个简单的例子,我想要做的(并且更容易解释):如果用户点击链接,从列表中删除该元素,控制器将处理回调,并且回调(这里有问题)将删除我点击的元素,所以在回调delete.js.erb只会说$(this).fadeOut();这就是为什么我要使用$(这)让我不必分配一个ID给每个元素(这将是世界的末日,只是更详细的标记)

的application.js

jQuery.ajaxSetup({ 'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript,application/javascript,text/html")} }) 

function _ajax_request(url, data, callback, type, method) { 
    if (jQuery.isFunction(data)) { 
     callback = data; 
     data = {}; 
    } 
    return jQuery.ajax({ 
     type: method, 
     url: url, 
     data: data, 
     success: callback, 
     dataType: type 
    }); 
} 

jQuery.extend({ 
    put: function(url, data, callback, type) { 
     return _ajax_request(url, data, callback, type, 'PUT'); 
    }, 
    delete_: function(url, data, callback, type) { 
     return _ajax_request(url, data, callback, type, 'DELETE'); 
    } 
}); 

jQuery.fn.submitWithAjax = function() { 
    this.unbind('submit', false); 
    this.submit(function() { 
     $.post(this.action, $(this).serialize(), null, "script"); 
     return false; 
    }) 
    return this; 
}; 

// Send data via get if <acronym title="JavaScript">JS</acronym> enabled 
jQuery.fn.getWithAjax = function() { 
    this.unbind('click', false); 
    this.click(function() { 
     $.get($(this).attr("href"), $(this).serialize(), null, "script"); 
     return false; 
    }) 
    return this; 
}; 

// Send data via Post if <acronym title="JavaScript">JS</acronym> enabled 
jQuery.fn.postWithAjax = function() { 
    this.unbind('click', false); 
    this.click(function() { 
     $.post($(this).attr("href"), $(this).serialize(), null, "script"); 
     return false; 
    }) 
    return this; 
}; 

jQuery.fn.putWithAjax = function() { 
    this.unbind('click', false); 
    this.click(function() { 
     $.put($(this).attr("href"), $(this).serialize(), null, "script"); 
     return false; 
    }) 
    return this; 
}; 

jQuery.fn.deleteWithAjax = function() { 
    this.removeAttr('onclick'); 
    this.unbind('click', false); 
    this.click(function() { 
     $.delete_($(this).attr("href"), $(this).serialize(), null, "script"); 
     return false; 
    }) 
    return this; 
}; 

// This will "ajaxify" the links 
function ajaxLinks(){ 
    $('.ajaxForm').submitWithAjax(); 
    $('a.get').getWithAjax(); 
    $('a.post').postWithAjax(); 
    $('a.put').putWithAjax(); 
    $('a.delete').deleteWithAjax(); 
} 

show.html.erb

<%= link_to 'Link Title', article_path(a, :sentiment => Article::Sentiment['Neutral']), :class => 'put' %> 

的两件事情结合将调用update.js.erb在轨,该文件中的代码作为阿贾克斯($。把在这种情况下)回调

更新.js.erb

// user feedback 
$("#notice").html('<%= flash[:notice] %>'); 

// update the background color 
$(this OR e.target).attr("color", "red"); 

回答

0

这无法实现,在我试图做到这一点的方法使它不可能,我无法通过的意见传递给JavaScript对象的引用。

解决方案是为每个项目分配ID,并通过它引用它们。

0

如果你的JS是来自服务器,实在没有办法,$(这)可以在同样的情况下进行操作。最接近你可以从服务器加载一些脚本,并在客户端功能的上下文中评估它。

我基本上每个需要操作的DOM元素都有一个id,并在我的脚本中引用它们。偶尔会有丑陋,但替代品更糟。

+0

我不会去投票,但事实并非如此。我也曾经这样想过,但看到我的帖子上面。 – 2010-02-04 08:42:57

0

如果你的JS是来自服务器, 实在没有办法,$(本) 可以在同样的情况下进行操作。您可以得到的最接近的 将从服务器加载 一些脚本,并且在您的客户端功能 的上下文中加载 。

事实并非如此

我基本上每一个我需要操作 DOM元素的ID,并 指他们我的脚本中。偶尔丑陋的是 ,但 替代品更糟。

我不认为这是丑陋的。

这个问题的关键是功能范围。让我告诉你我的意思。您需要创建一个在您发送XHR呼叫之前调用的函数。在你的情况,你有一个click事件做,所以让我告诉你你量身打造一个例子:

$('#somelink').click(function() 
{ 
    // this stores the location of the current "this" value 
    // into this function, and will available even after we 
    // end this function (and will still live while the XHR's 
    // callback is being executed 

    var theLink = this; 

    // fire the AJAX call 

    $.post 
    (
     'some/url', 

     { 'some':'data' }, // optional 

     function() 
     { 
      // use theLink however you want 
      // it'll still be there 

      // also, if you're sending in callbacks 
      // as variables, you can safely say 

      hideAndStore.call(theLink, data); 

      // which executes callback(), overriding 
      // "this" with theLink (your DOM node) 
      // and sending in the responseText as the 
      // first argument 
     } 
    ); 
}); 

,然后你可以让你的回调是这样的:

function hideAndStore(response) 
{ 
    // you can safely use "this" as the DOM node 
    $(this).css({ 'display':'none' }); 

    // and you can do whatever you wish with the response 
    window.globalData = response; 
} 

哪里你会让它做你想做的事情,哈哈。

有关的JavaScript改变“这个”价值功能的详细信息,在MDC

https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Applyhttps://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Function/Call

+0

似乎是一个很好的解决方案。我正在寻找的是一种提供回调对象的方式,以便我可以参考它。因此,使用我发布的示例使用{http://pastie.org/809431}与回调“脚本”(我认为)的方法 - 我可以修改该脚本作为您建议我调用的方法的主体? callbackMethod.call(_partial,theLink,data)其中partial是脚本 – Rabbott 2010-02-04 15:23:23

+0

_partial =脚本.. update.js.erb例如 – Rabbott 2010-02-04 15:25:46

+0

您无法使其执行文件,但可以将脚本标记添加到DOM (''('body').append('');'),或者在执行AJAX调用之前简单地包含脚本并将脚本内容封装在函数myExtraJavaScript() {/ *把代码放在这里* /}'然后在回调中调用'myExtraJavaScript' – 2010-02-05 23:03:33

0

你在你发回的JavaScript做检查.apply.call?也许你可以发回一些HTML或JSON并在回调中对其进行操作。

$('a:clickable').bind('click', function() { 
    var elem = $(this); 
    $.ajax({ 
    url: ..., 
    dataType: 'json', 
    success: function(data) { 
     // elem is still in scope 
     elem.addClass(data.class_to_add_to_link); 
    } 
    }); 
}); 
+0

那么给出一个类似于我想要做的事情的简单例子(并且更容易解释):如果用户点击链接,从列表中删除该元素,控制器将处理回调,并且回调(这里有问题)将删除我点击的元素,所以在回调delete.js.erb只会说$(this)。消退();这就是为什么我想使用$(this),这样我就不必为每个元素分配一个ID(这将是世界的尽头,只是更详细的标记) – Rabbott 2010-02-19 03:38:25

+0

我不确定你的意思是“控制器会处理回调“。正如我在上面写的,您的前端JavaScript“回调”将成为成功处理程序。轨道控制器会回应一些状态或一些新的HTML或任何。如果调用成功,这里的前端知道它需要的所有东西,被点击的东西,上下文,任何关闭变量等等。或者我还不知道你在你的工作中想做什么(以及为什么)轨道控制器,以及为什么它不能完成客户端。 – aceofspades 2010-02-19 16:42:08

1

的jQuery已经处理this问题为您与事件的属性:

$("a").click(function(e){ 
    e.preventDefault(); 
    $("#foo").fadeIn(3000, function(){ 
    $(e.target).text("Foo loaded"); 
    }); 
});​​​ 

注意我如何可以通过其event指回主链路。任何在内部处理的事件都是如此。只要给他们一个独特的名字,比如e2,e3等。不需要再不停地写另一个var item = $(this)一行来跟踪this三个事件。

在线演示:http://jsbin.com/egelu3/edit

+0

这真是太棒了,在脚本之外工作 - 所以它的CLOSER!这里是被称为http://pastie.org/832155的JavaScript,所以你可以看到点击事件提供了'e',但你也看到'脚本',该脚本显然不知道e ..和脚本即时通讯试图访问$(this)或e在你的情况下,你看到一种方式来提供它吗? – Rabbott 2010-02-19 04:22:22

+0

我不熟悉'$ .put()'。 '“script”是一个表示要调用的函数的字符串吗?如果是这样,你是否不能将'e'作为参数传递给该函数? – Sampson 2010-02-19 04:30:23

+0

脚本实际上是put方法的'type'参数,这是我从教程中学到的东西。本网站http://homework.nwsnet.de/news/9132_put-and-delete-with-jquery有类似的东西。对不起,我也不太了解它。 – Rabbott 2010-02-19 04:48:41