为什么我动态添加(返回)jQuery 处理程序失败?

Why does my dynamically added (back) jQuery handler fail?

我正在单击按钮时替换页面上的 html - 所有内容,包括 css 和 jQuery。 jQuery(按钮单击事件处理程序)第一次起作用,但之后就不起作用了;事实上,它会抛出一个异常。

此静态 ajax jquery 回调代码包含以下内容:

url: '@Url.RouteUrl(routeName: "QuadrantData", routeValues: new { httpRoute = true, unit = "un", begdate = "bd", enddate = "ed" })'
      .replace("un", encodeURIComponent(_unit))
      .replace("bd", encodeURIComponent(_begdate))
      .replace("ed", encodeURIComponent(_enddate)),

...在运行时转换为:

url: '/api/un/bd/ed'
      .replace("un", encodeURIComponent(_unit))
      .replace("bd", encodeURIComponent(_begdate))
      .replace("ed", encodeURIComponent(_enddate)),

此代码是按钮事件处理程序中 ajax 调用的一部分。如前所述,它在第一次单击按钮时完美运行,但在 html(以及 css 和 jquery)响应该单击被替换后,我得到以下信息:

HTTP Error 404.0 - Not Found
The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

Most likely causes:
The directory or file specified does not exist on the Web server.
The URL contains a typographical error.
A custom filter or module, such as URLScan, restricts access to the file.

Things you can try:
Create the content on the Web server.
Review the browser URL.
Check the failed request tracing log and see which module is calling SetStatus. For more information, click here.

Detailed Error Information:
Module     IIS Web Core
Notification       MapRequestHandler
Handler    StaticFile
Error Code     0x80070002
Requested URL      http://localhost:52194/@Url.RouteUrl(routeName: "QuadrantData", routeValues: new { httpRoute = 
true, Abuelosit = "un", begdate = "2016-08-28", enddate = "2016-08-31" })?_=1473366761632
Physical Path      C:\Projects\ProActWebReports\ProActWebReports\@Url.RouteUrl(routeName: "QuadrantData", routeValues: 
new { httpRoute = true, Abuelosit = "un", begdate = "2016-08-28", enddate = "2016-08-31" })

Logon Method       Anonymous
Logon User     Anonymous
Request Tracing Directory      C:\Users\cshannon\Documents\IISExpress\TraceLogFiles\PROACTWEBREPORTS

More Information:
This error means that the file or directory does not exist on the server. Create the file or directory and try the request again.

删除了哪些资源?哪个"file or directory does not exist on the server"?实际上,异常消息中看起来很可疑的是:

*Abuelosit = "un", begdate = "2016-08-28", enddate = "2016-08-31"* 

应该是:

*unit = "Abuelos", begdate = "2016-08-28", enddate = "2016-08-31"* 

...所以似乎 "Abuelos" 和 "unit" 正在以某种方式得到 mangled/jumbled - Abuelosit = "un"应该是 unit = "Abuelos"。如果这是问题所在,我该如何纠正?

顺便说一句,调用的 REST 方法(第一次单击按钮时)是:

[HttpGet]
[Route("{unit}/{begdate}/{enddate}", Name = "QuadrantData")] 
public HttpResponseMessage GetQuadrantData(string unit, string begdate, 
    string enddate)
{
    _unit = unit;
    _beginDate = begdate;
    _endDate = enddate;
    string beginningHtml = GetBeginningHTML();
    string bodyBeginningHtml = GetBodyBeginHTML();
    string top10ItemsPurchasedHtml = GetTop10ItemsPurchasedHTML();
    string pricingExceptionsHtml = GetPricingExceptionsHTML();
    string forecastedSpendHtml = GetForecastedSpendHTML();
    string deliveryPerformanceHtml = GetDeliveryPerformanceHTML();
    string endingHtml = GetEndingHTML();
    String HtmlToDisplay = string.Format("{0}{1}{2}{3}{4}{5}{6}",
        beginningHtml,
        bodyBeginningHtml,
        top10ItemsPurchasedHtml,
        pricingExceptionsHtml,
        forecastedSpendHtml,
        deliveryPerformanceHtml,
        endingHtml);

    return new HttpResponseMessage()
    {
        Content = new StringContent(
            HtmlToDisplay,
            Encoding.UTF8,
            "text/html"
        )
    };
}

更新

对于后代,这是旧代码(已注释掉)和来自 Ricardo 的新代码:

首先,在 Index.cshtml(原始 html)中:

//$("#btnGetData").click(function () {
$("body").on( "click", "#btnGetData", function() {

在控制器代码中,我动态生成 html 来替换之前的:

//builder.Append("$(\"#btnGetData\").click(function () {");
builder.Append("$(\"body\").on( \"click\", \"#btnGetData\", function() {");

这现在工作得很好。

根据我的经验,如果 AJAX 请求第一次工作正常而第二次失败,并且您正在用 AJAX 中的新 HTML 替换原来的 HTML =] request,表示原来的click handlers没有了

如果您像这样将点击处理程序附加到按钮:

$("button.someAction").click(function() {
    $.ajax("/api/a/b/c");
    // etc.
});

一旦 AJAX 请求完成,它们就会消失。当您单击不再具有事件处理程序的按钮时,它会尝试向服务器提交内容,您会得到一个奇怪的 URL。

您应该为它们分配 .on() 而不是 click().on() 应该分配给在新请求中替换内部的容器。

$("#container").on( "click", "button.someAction", function() {
  $.ajax("/api/a/b/c");
});

这样,按钮上的操作将在所有请求中保持不变。

希望对您有所帮助。

您的问题在这里:

url: '@Url.RouteUrl(routeName: "QuadrantData", routeValues: new { httpRoute = true, unit = "un", begdate = "bd", enddate = "ed" })'
      .replace("un", encodeURIComponent(_unit))
      .replace("bd", encodeURIComponent(_begdate))
      .replace("ed", encodeURIComponent(_enddate)),

上面的代码,第一次,被解释并正确成为你期望的URL。

第二次作为字符串处理.

并且 URL 包含该字符串,不是 你的 API url:

Requested URL      http://localhost:52194/@Url.RouteUrl(routeName:
"QuadrantData", routeValues: new { httpRoute = 
true, Abuelosit = "un", begdate = "2016-08-28", 
enddate = "2016-08-31" })?_=1473366761632

这就是 "Unit=abuelos" 变成 "abuelosit" 的原因。因为你替换了"un",而"unit"这个词包含了"un"。所以 "unit" 变成 "abuelosit"(就像 "unique" 变成 "abuelosique")。

您需要每次都解析您的@variable ,或者将其保存在某个地方,以防万一,我还建议您使用一些更有特色的字符串:

var baseUrl = '@Url...unit="_Xx_un_xX_"...

然后每次都复制baseUrl:

url = baseUrl.replace('_Xx_un_xX_', encodeURIComponent(_unit)...