1

是否可以获得对triggerElement在函数中调用 Ajax 请求的引用onSuccess

<%=Ajax.ActionLink("x", a, r, New AjaxOptions With {.OnSuccess = _
         "function(context) {alert('get triggerElement reference here?');}" })%>
4

1 回答 1

6

页面呈现为:
<a href="/<whatever>/<action>" onclick=" Sys.Mvc.AsyncHyperlink.handleClick ( this , new Sys.UI.DomEvent(event), { injectionMode: Sys.Mvc. InsertionMode.replace, onSuccess: Function.createDelegate(this, function(context) { alert('get triggerElement reference here?'); }) });">x</a>

那么让我们看一下Sys.Mvc.AsyncHyperlink.handleClick内部Scripts\MicrosoftMvcAjax.debug.js

Sys.Mvc.AsyncHyperlink.handleClick = function Sys_Mvc_AsyncHyperlink$handleClick(anchor, evt, ajaxOptions) {
    /// omitted doc comments
    evt.preventDefault();
    Sys.Mvc.MvcHelpers._asyncRequest(anchor.href, 'post', '', anchor, ajaxOptions);
}

所以 ActionLink 被渲染到一个锚(“a”)标签,带有一个“onclick”事件,它使用Sys.Mvc.AsyncHyperlink.handleClickthis作为参数之一,映射到anchor
然后是这个Sys.Mvc.MvcHelpers._asyncRequest锚点作为第四个参数的调用。让我们看看Sys.Mvc.MvcHelpers._asyncRequest

Sys.Mvc.MvcHelpers._asyncRequest = function Sys_Mvc_MvcHelpers$_asyncRequest(url, verb, body, triggerElement, ajaxOptions) {
    /// omitted documentation
    if (ajaxOptions.confirm) {
        if (!confirm(ajaxOptions.confirm)) {
            return;
        }
    }
    if (ajaxOptions.url) {
        url = ajaxOptions.url;
    }
    if (ajaxOptions.httpMethod) {
        verb = ajaxOptions.httpMethod;
    }
    if (body.length > 0 && !body.endsWith('&')) {
        body += '&';
    }
    body += 'X-Requested-With=XMLHttpRequest';
    var requestBody = '';
    if (verb.toUpperCase() === 'GET' || verb.toUpperCase() === 'DELETE') {
        if (url.indexOf('?') > -1) {
            if (!url.endsWith('&')) {
                url += '&';
            }
            url += body;
        }
        else {
            url += '?';
            url += body;
        }
    }
    else {
        requestBody = body;
    }
    var request = new Sys.Net.WebRequest();
    request.set_url(url);
    request.set_httpVerb(verb);
    request.set_body(requestBody);
    if (verb.toUpperCase() === 'PUT') {
        request.get_headers()['Content-Type'] = 'application/x-www-form-urlencoded;';
    }
    request.get_headers()['X-Requested-With'] = 'XMLHttpRequest';
    var updateElement = null;
    if (ajaxOptions.updateTargetId) {
        updateElement = $get(ajaxOptions.updateTargetId);
    }
    var loadingElement = null;
    if (ajaxOptions.loadingElementId) {
        loadingElement = $get(ajaxOptions.loadingElementId);
    }
    var ajaxContext = new Sys.Mvc.AjaxContext(request, updateElement, loadingElement, ajaxOptions.insertionMode);
    var continueRequest = true;
    if (ajaxOptions.onBegin) {
        continueRequest = ajaxOptions.onBegin(ajaxContext) !== false;
    }
    if (loadingElement) {
        Sys.UI.DomElement.setVisible(ajaxContext.get_loadingElement(), true);
    }
    if (continueRequest) {
        request.add_completed(Function.createDelegate(null, function(executor) {
            Sys.Mvc.MvcHelpers._onComplete(request, ajaxOptions, ajaxContext);
        }));
        request.invoke();
    }
}

所以原来的锚点现在是triggerElement,但是正如你所看到的,这个参数从未在函数体中使用过。
因此,如果您想对 triggerElement 进行某种“正式”(或记录)引用 - 没有这样的事情。
但是,嘿,它是 JavaScript,所以只要浏览器没有移动到另一个页面,您几乎可以访问任何东西,包括调用堆栈。例如:

<script type="text/javascript">
function a(p, q)
{
    b();
}

function b() {
    var x = arguments.caller[1];
    alert(x); // boo!
}

a(789, "boo!");

</script>

所以最终你可以破解它并访问原始锚。我建议您执行以下操作:

  • 编写一个要在 OnBegin.
  • 在此函数中,访问 original triggerElement,并将其作为属性添加到 original ajaxOptions(也可以访问)
  • 然后,在OnSuccess函数中,访问您被黑的 ajaxOptions.
于 2009-07-01T12:39:00.773 回答