在 asp.net mvc-3 中使用 Unobtrusive ajax 时上下文丢失

2023-12-19


我刚刚转向使用 mvc-3 附带的不显眼的 ajax,但它在某一点上崩溃了。 这是我的链接

<%: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>

i found 本文 http://forums.asp.net/p/1650310/4433012.aspx/1?Re%20MVC%203%20Master%20Detail%20view%20inserts%20new%20detail%20records%20instead%20of%20updating%20existing%20records%20on%20controller%20UpdateModel其中伊姆兰描述了如何解决该问题。但它涉及向 jquery.unobtrusive-ajax.js 添加一行。它有副作用吗?我应该更改 jquery 文件吗?如果不是,我如何在不更改 jquery.unobtrusive-ajax.js 文件的情况下获取被单击的链接的 id


这是经过编辑的 MS 不显眼的 AJAX 的完整副本,包括新的缩小版本。它包含上下文(源元素丢失)修复以及另一个重要修复,其中记录的“取消”类在应用于提交项目时不被遵守(应该阻止验证,但不会)。

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)

我很失望这些关键的正常行为修复在这么长的时间内没有得到纠正(特别是因为只有三个简单的编辑)。即使是 2013 年 9 月最新版本的 AJAX 工具包仍在使用现在遗留的“Sys”Microsoft AJAX 库,而世界其他地方已经迁移到 jQuery UI。也许这一切都会通过 Visual Studio 2013 特别是 MVC 5 的 RTM 得到澄清?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 asp.net mvc-3 中使用 Unobtrusive ajax 时上下文丢失 的相关文章

随机推荐

  • Python 的 eyesed3 包未正确设置 ID3 元数据

    为此 我使用 Python 2 7 13 Windows 10 和 eyed3 包 如文档所示 here http eyed3 nicfit net Goal 我正在尝试创建一个脚本 可以为缺少信息的 MP3 文件输入任何所需的 ID3 元
  • Dict 相对于 OrderedDict 的优点[重复]

    这个问题在这里已经有答案了 我觉得 Python 字典不按插入顺序存储键很烦人 最近 我开始使用 OrderedDict 它使用起来更方便 因为它克服了这个缺点 例如 迭代 CSV 文件的列 其中列顺序应该与字典的键顺序匹配 也就是说 字典
  • jquery最好的弹出框插件[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 来自右值的非常量类型引用

    考虑以下代码 class Widget template
  • 事件驱动的 PHP 框架? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我想知道是否有任何完全事件驱动的 PHP 框架基于依赖注入以进行解耦 我知道有一些框架可以use这些模
  • Visual C++ 2008 Express 的 C 编译器位于磁盘上的什么位置?

    我正在尝试设置Hg Git Mercurial 扩展 http hg git github com 建议使用 Microsoft Visual C 2008 的 C 编译器 我已经安装了 Visual C 2008 但我无法确定 C 编译器
  • 为什么此 ctypes 代码不能与 Python 3.3 一起使用,但可以与 Python 2.7 一起使用?

    所以我试图制作一个Python 3 3 程序来使用ctypes 模块更改Windows 桌面背景 我在 Python 2 7 中测试了以下代码 它运行得很好 但它不适用于 Python 3 3 我使用的是 Windows 7 代码如下 im
  • ajax中传递参数得到空值

    我正在使用 ajax 调用动作控制器 但我传递的参数data当动作控制器收到它时 属性始终为空 这里会发生什么 jQuery 函数 function PostOrder var id aslink data customerid var u
  • 使用会话变量实现安全性,它是如何不安全的

    我正在 dotnet 中做基于网络的项目 目前我正在使用会话变量来实现安全性 我将当前用户 ID 和用户类型保留在会话中 并通过这些会话变量对用户进行身份验证 例如 Session UserId Session UserName 和 Ses
  • mailto 链接在 Chrome 浏览器中不起作用(版本:18.0.1025.152 m)

    mailto 链接在 Google Chrome 浏览器中不起作用 版本 18 0 1025 152 m a href Send mail a 我在ff和chrome中使用了上面的代码 在 ff 中工作正常 但在 chrome 中不行 你可
  • 判断平面上的4个点是否构成一个矩形?

    有人可以用 C 风格的伪代码向我展示如何编写一个函数 以您喜欢的方式表示点 如果 4 个点 函数的参数 形成一个矩形 则该函数返回 true 否则返回 false 我想出了一个解决方案 首先尝试找到 2 个具有相等 x 值的不同点对 然后对
  • n 个圆盘/圆的交点的质心 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 假设n个圆盘 圆共享一个公共区域 这意味着它们每两个都相交 并且我们知道它们的坐标 x1 y1 r1 x2 y2 r2 xn yn rn 其中xi y
  • 尝试创建“收藏夹”按钮以在收藏夹列表中添加项目

    我正在尝试在 CollectionViewCell 上创建收藏夹按钮 用于将项目保存在收藏夹列表中 当我点击收藏夹图标按钮时 它成功地将选定的单元格项目添加到收藏夹列表类的数组中 并且也显示在收藏夹列表中 当我点击收藏夹按钮时 它会根据已保
  • knockout.js 完成渲染所有元素后的成功回调

    我已经实现了淘汰 foreach 绑定 在同一页面中具有多个模板 这里给出了一个示例 我感兴趣的是找出块何时完成渲染 我尝试过afterRender and afterAdd 但我猜它会针对每个元素运行 而不是在整个循环完成后运行 ul l
  • React Native - 以编程方式检查是否启用了远程 JS 调试

    在 React Native 上 我怎么知道是否 Debug JS Remotely 已启用 我尝试查看RN docs https facebook github io react native docs debugging html和各种
  • 博览会中相机的媒体流输出反应本机

    我正在尝试制作一个点对点视频通话应用程序 我正在使用expo作为前端 我想知道如何从移动摄像头获取媒体流并将其传递给对等方 目前这可以使用react native webrtc来实现 但expo不支持这个包 那么有没有其他方法可以从相机获取
  • UNIX 域套接字无法跨用户访问?

    我正在 Red Hat Enterprise 上运行客户端 服务器应用程序 使用 ZMQ 进行消息传递 用于将客户端与服务器关联的 IPC 套接字是使用 Unix 域套接字实现的 如果用户 A 启动服务器进程 则似乎只有用户 A 启动的客户
  • EnsureSuccessStatusCode 的使用以及它抛出的 HttpRequestException 的处理

    使用模式是怎样的HttpResponseMessage EnsureSuccessStatusCode 它处理消息的内容并抛出HttpRequestException 但我不明白如何以编程方式处理它与通用的不同Exception 例如 它不
  • 如何获取偏好片段中的偏好值

    我想在自定义首选项屏幕中显示首选项的值 为此 我需要获取首选项片段中的值 在本例中为字符串 在非片段 活动 中 我通过以下方式获取值 final SharedPreferences prefs PreferenceManager getDe
  • 在 asp.net mvc-3 中使用 Unobtrusive ajax 时上下文丢失

    我刚刚转向使用 mvc 3 附带的不显眼的 ajax 但它在某一点上崩溃了 这是我的链接 这是我的 js 函数 成功时将被调用