Отсутствует контекст при использовании ненавязчивого ajax в asp.net mvc-3 - PullRequest
2 голосов
/ 26 мая 2011


Я только что перешел на ненавязчивый ajax, который поставляется с mvc-3, но он ломается в одной точке.Вот моя ссылка

<%:Ajax.ActionLink("Edit", "Home", "Edit", new{id = Model.SomeID}, new AjaxOptions{OnSuccess = "DoSomething"})%>

это моя функция js, которая будет вызываться при успехе

<script type="text/javascript">
function DoSomething(data)
{
    var clickedLinkID = this.id; // this line breaks it used to work with microsoft ajax
    //rest of code goes here
}
</script>

я нашел эту статью , в которой imran описывает, как решитьэта проблема.но это включает добавление одной строки в jquery.unobtrusive-ajax.js.Есть ли у него побочные эффекты?я должен изменить файлы jquery?если нет, то как я могу получить идентификатор ссылки, по которой щелкнули, без изменения файла jquery.unobtrusive-ajax.js

Ответы [ 2 ]

0 голосов
/ 15 октября 2013

Вот полная копия отредактированного ненавязчивого AJAX-файла MS, включая недавно уменьшенную версию.Он содержит исправление контекста (отсутствует исходный элемент), а также еще одно важное исправление, благодаря которому документированный класс «отмены» не учитывался при применении к отправке элементов (должен препятствовать проверке, но не делает этого).

jquery.unobtrusive-ajax

    /*!
    ** Unobtrusive Ajax support library for jQuery
    ** Copyright (C) Microsoft Corporation. All rights reserved.
    ** Fixed version (see full comments for details)
    */

    /*
        Fix for "validation ignores cancel class" applied from
        http://stackoverflow.com/questions/11561496/jquery-unobtrusive-validation-ignores-cancel-class-on-submit-button-if-used-in 

        Line 144 changed to:
            // Fixed to pass class name (needed for other fixes and useful anyway)
            $(form).data(data_click, name ? [{ name: name, value: evt.target.value, className: evt.target.className }] : []);

        Line 154 changed to:
            // Fixed for "cancel" class not honoured (so correct documented behavior of non-validating/cancel buttons are restored)
            if (clickInfo.length > 0 && clickInfo[0].className.indexOf('cancel') < 0 && !validate(this)) {

    */

    /*
        Fix for "source element missing on post-back event handler" applied from
        http://forums.asp.net/t/1663285.aspx?How+to+get+source+Element+when+using+Unobtrusive+Ajax+in+ASP+NET+MVC+3

        Line 101 inserted:
            // Fixed to pass source element in context (so source element can be discovered in handlers)
            options.context = element;

    */

    /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
    /*global window: false, jQuery: false */

    (function ($) {
        var data_click = "unobtrusiveAjaxClick",
            data_validation = "unobtrusiveValidation";

        function getFunction(code, argNames) {
            var fn = window, parts = (code || "").split(".");
            while (fn && parts.length) {
                fn = fn[parts.shift()];
            }
            if (typeof (fn) === "function") {
                return fn;
            }
            argNames.push(code);
            return Function.constructor.apply(null, argNames);
        }

        function isMethodProxySafe(method) {
            return method === "GET" || method === "POST";
        }

        function asyncOnBeforeSend(xhr, method) {
            if (!isMethodProxySafe(method)) {
                xhr.setRequestHeader("X-HTTP-Method-Override", method);
            }
        }

        function asyncOnSuccess(element, data, contentType) {
            var mode;

            if (contentType.indexOf("application/x-javascript") !== -1) {  // jQuery already executes JavaScript for us
                return;
            }

            mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase();
            $(element.getAttribute("data-ajax-update")).each(function (i, update) {
                var top;

                switch (mode) {
                case "BEFORE":
                    top = update.firstChild;
                    $("<div />").html(data).contents().each(function () {
                        update.insertBefore(this, top);
                    });
                    break;
                case "AFTER":
                    $("<div />").html(data).contents().each(function () {
                        update.appendChild(this);
                    });
                    break;
                default:
                    $(update).html(data);
                    break;
                }
            });
        }

        function asyncRequest(element, options) {
            var confirm, loading, method, duration;

            confirm = element.getAttribute("data-ajax-confirm");
            if (confirm && !window.confirm(confirm)) {
                return;
            }

            loading = $(element.getAttribute("data-ajax-loading"));
            duration = element.getAttribute("data-ajax-loading-duration") || 0;

            $.extend(options, {
                type: element.getAttribute("data-ajax-method") || undefined,
                url: element.getAttribute("data-ajax-url") || undefined,
                beforeSend: function (xhr) {
                    var result;
                    asyncOnBeforeSend(xhr, method);
                    result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments);
                    if (result !== false) {
                        loading.show(duration);
                    }
                    return result;
                },
                complete: function () {
                    loading.hide(duration);
                    getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments);
                },
                success: function (data, status, xhr) {
                    asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
                    getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments);
                },
                error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"])
            });

            options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });

            // Fixed to pass source element in context (so source element can be discovered in handlers)
            options.context = element;

            method = options.type.toUpperCase();
            if (!isMethodProxySafe(method)) {
                options.type = "POST";
                options.data.push({ name: "X-HTTP-Method-Override", value: method });
            }

            $.ajax(options);
        }

        function validate(form) {
            var validationInfo = $(form).data(data_validation);
            return !validationInfo || !validationInfo.validate || validationInfo.validate();
        }

        $(document).on("click", "a[data-ajax=true]", function (evt) {
            evt.preventDefault();
            asyncRequest(this, {
                url: this.href,
                type: "GET",
                data: []
            });
        });

        $(document).on("click", "form[data-ajax=true] input[type=image]", function (evt) {
            var name = evt.target.name,
                $target = $(evt.target),
                form = $target.parents("form")[0],
                offset = $target.offset();

            $(form).data(data_click, [
                { name: name + ".x", value: Math.round(evt.pageX - offset.left) },
                { name: name + ".y", value: Math.round(evt.pageY - offset.top) }
            ]);

            setTimeout(function () {
                $(form).removeData(data_click);
            }, 0);
        });

        $(document).on("click", "form[data-ajax=true] :submit", function (evt) {
            var name = evt.target.name,
                form = $(evt.target).parents("form")[0];

            // Fixed to pass class name (needed for other fixes and useful anyway)
            $(form).data(data_click, name ? [{ name: name, value: evt.target.value, className: evt.target.className }] : []);

            setTimeout(function () {
                $(form).removeData(data_click);
            }, 0);
        });

        $(document).on("submit", "form[data-ajax=true]", function (evt) {
            var clickInfo = $(this).data(data_click) || [];
            evt.preventDefault();
            // Fixed for "cancel" class not honoured (so correct documented behavior of non-validating/cancel buttons are restored)
            if (clickInfo.length > 0 && clickInfo[0].className.indexOf('cancel') < 0 && !validate(this)) {
                return;
            }
            asyncRequest(this, {
                url: this.action,
                type: this.method || "GET",
                data: clickInfo.concat($(this).serializeArray())
            });
        });
    }(jQuery));

jquery.unobtrusive-ajax-fixed.min.js

    /*
    ** Unobtrusive Ajax support library for jQuery
    ** Copyright (C) Microsoft Corporation. All rights reserved.
    ** Fixed version (see full comments for details)
    */
    (function(a){var b="unobtrusiveAjaxClick",g="unobtrusiveValidation";function c(d,b){var a=window,c=(d||"").split(".");while(a&&c.length)a=a[c.shift()];if(typeof a==="function")return a;b.push(d);return Function.constructor.apply(null,b)}function d(a){return a==="GET"||a==="POST"}function f(b,a){!d(a)&&b.setRequestHeader("X-HTTP-Method-Override",a)}function h(c,b,e){var d;if(e.indexOf("application/x-javascript")!==-1)return;d=(c.getAttribute("data-ajax-mode")||"").toUpperCase();a(c.getAttribute("data-ajax-update")).each(function(f,c){var e;switch(d){case"BEFORE":e=c.firstChild;a("<div />").html(b).contents().each(function(){c.insertBefore(this,e)});break;case"AFTER":a("<div />").html(b).contents().each(function(){c.appendChild(this)});break;default:a(c).html(b)}})}function e(b,e){var j,k,g,i;j=b.getAttribute("data-ajax-confirm");if(j&&!window.confirm(j))return;k=a(b.getAttribute("data-ajax-loading"));i=b.getAttribute("data-ajax-loading-duration")||0;a.extend(e,{type:b.getAttribute("data-ajax-method")||undefined,url:b.getAttribute("data-ajax-url")||undefined,beforeSend:function(d){var a;f(d,g);a=c(b.getAttribute("data-ajax-begin"),["xhr"]).apply(this,arguments);a!==false&&k.show(i);return a},complete:function(){k.hide(i);c(b.getAttribute("data-ajax-complete"),["xhr","status"]).apply(this,arguments)},success:function(a,e,d){h(b,a,d.getResponseHeader("Content-Type")||"text/html");c(b.getAttribute("data-ajax-success"),["data","status","xhr"]).apply(this,arguments)},error:c(b.getAttribute("data-ajax-failure"),["xhr","status","error"])});e.data.push({name:"X-Requested-With",value:"XMLHttpRequest"});e.context=b;g=e.type.toUpperCase();if(!d(g)){e.type="POST";e.data.push({name:"X-HTTP-Method-Override",value:g})}a.ajax(e)}function i(c){var b=a(c).data(g);return!b||!b.validate||b.validate()}a(document).on("click","a[data-ajax=true]",function(a){a.preventDefault();e(this,{url:this.href,type:"GET",data:[]})});a(document).on("click","form[data-ajax=true] input[type=image]",function(c){var g=c.target.name,d=a(c.target),f=d.parents("form")[0],e=d.offset();a(f).data(b,[{name:g+".x",value:Math.round(c.pageX-e.left)},{name:g+".y",value:Math.round(c.pageY-e.top)}]);setTimeout(function(){a(f).removeData(b)},0)});a(document).on("click","form[data-ajax=true] :submit",function(c){var e=c.target.name,d=a(c.target).parents("form")[0];a(d).data(b,e?[{name:e,value:c.target.value,className:c.target.className}]:[]);setTimeout(function(){a(d).removeData(b)},0)});a(document).on("submit","form[data-ajax=true]",function(d){var c=a(this).data(b)||[];d.preventDefault();if(c.length>0&&c[0].className.indexOf("cancel")<0&&!i(this))return;e(this,{url:this.action,type:this.method||"GET",data:c.concat(a(this).serializeArray())})})})(jQuery)

Я разочарован тем, что эти критические исправления нормального поведения не исправлялись в течение столь длительного времени (особенно с тех пор, какесть только три простых правки).Даже последний выпуск инструментария AJAX в сентябре 2013 года по-прежнему использует устаревшую библиотеку Microsoft AJAX «Sys», в то время как остальная часть мира уже перешла на пользовательский интерфейс jQuery.Может быть, все это будет разъяснено с помощью окончательной первоначальной версии Visual Studio 2013, в частности MVC 5?

0 голосов
/ 26 мая 2011

Поскольку вы сейчас используете jQuery, вам нужно обернуть его в $, чтобы получить контекст. Так что код будет что-то вроде

$(this).addClass("someclass");

Более подробную информацию можно найти в документации API здесь .

...