使用 ASP.NET MVC 在 JS 文件中为 jQuery 设置 ajax url
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/376644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting ajax url for jQuery in JS file using ASP.NET MVC
提问by Schotime
When doing a Ajax call to an MVC action currently I have my javascript inside the View, not inside its own JS file.
当前对 MVC 操作执行 Ajax 调用时,我的 javascript 位于视图中,而不是它自己的 JS 文件中。
It is then very easy to do this:
然后很容易做到这一点:
var xhr = $.ajax({
url: '<%= Url.Action("DisplayItem","Home") %>/' + el1.siblings("input:hidden").val(),
data: { ajax: "Y" },
cache: false,
success: function(response) { displayMore(response, el1, xhr) }
});
...then including the URL in the ajax call using Url.Action()
inside the JS is pretty easy. How could i move this do its own JS file when without hard coding the URL?
...然后Url.Action()
在 JS 内部使用的 ajax 调用中包含 URL非常简单。在没有硬编码 URL 的情况下,我怎么能移动它来做它自己的 JS 文件?
采纳答案by Simon_Weaver
This way fully uses MVC Routing so you can fully take advantage of the MVC framework. Inspired by stusmith's answer.
这种方式充分利用了 MVC 路由,因此您可以充分利用 MVC 框架。灵感来自斯图史密斯的回答。
Here I have an action in ApplicationController
for dynamic javascript for this URL :
在这里,我ApplicationController
对这个 URL 的动态 javascript有一个操作:
/application/js
I'm including static files here because I want just one master javascript file to download. You can choose to just return the dynamic stuff if you want:
我在这里包含静态文件,因为我只想下载一个主 JavaScript 文件。如果需要,您可以选择只返回动态内容:
/// <summary>
/// Renders out javascript
/// </summary>
/// <returns></returns>
[OutputCache(CacheProfile = "Script")]
[ActionName("js")]
public ContentResult RenderJavascript()
{
StringBuilder js = new StringBuilder();
// load all my static javascript files
js.AppendLine(IO.File.ReadAllText(Request.MapPath("~/Scripts/rr/cart.js")));
js.AppendLine(";");
// dynamic javascript for lookup tables
js.AppendLine(GetLookupTables());
js.AppendLine(";");
return new ContentResult()
{
Content = js.ToString(),
ContentType = "application/x-javascript"
};
}
This is the helper function that creates our lookup table. Just add in a line for each RouteUrl you want to use.
这是创建我们的查找表的辅助函数。只需为您要使用的每个 RouteUrl 添加一行。
[NonAction]
private string GetLookupTables()
{
StringBuilder js = new StringBuilder();
// list of keys that correspond to route URLS
var urls = new[] {
new { key = "updateCart", url = Url.RouteUrl("cart-route", new { action = "updatecart" }) },
new { key = "removeItem", url = Url.RouteUrl("cart-route", new { action = "removeitem" }) }
};
// lookup table function
js.AppendLine("// URL Lookuptable");
js.AppendLine("$.url=function(url) {");
js.AppendLine("var lookupTable = " + new JavaScriptSerializer().Serialize(urls.ToDictionary(x=>x.key, x=>x.url)) + ";");
js.AppendLine("return lookupTable[url];");
js.AppendLine("}");
return js.ToString();
}
This generates the following dynamic javascript, which is basically just a lookup table from an arbitrary key to the URL I need for my action method :
这将生成以下动态 javascript,它基本上只是一个从任意键到我的操作方法所需的 URL 的查找表:
// URL Lookuptable
$.url=function(url) {
var lookupTable = {"updateCart":"/rrmvc/store/cart/updatecart","removeItem":"/rrmvc/store/cart/removeitem"};
return lookupTable[url];
}
In cart.js I can have a function like this. Note that the url parameter is taken from the lookup table :
在cart.js 中,我可以有这样的功能。请注意, url 参数取自查找表:
var RRStore = {};
RRStore.updateCart = function(sku, qty) {
$.ajax({
type: "POST",
url: $.url("updateCart"),
data: "sku=" + sku + "&qty=" + qty,
dataType: "json"
// beforeSend: function (){},
// success: function (){},
// error: function (){},
// complete: function (){},
});
return false;
};
};
I can call it from anywhere with just :
我可以从任何地方调用它:
RRStore.updateCart(1001, 5);
This seemed to be the only way I could come up with that would allow me to use routing in a clean way. Dynamically creating URLS in javascript is icky and hard to test. Testing types can add in a layer somewhere in here to easily facilitate testing.
这似乎是我能想到的唯一方法,可以让我以干净的方式使用路由。在 javascript 中动态创建 URL 很麻烦且难以测试。测试类型可以在这里的某处添加一个层,以方便测试。
回答by Sam
The way I do it is generate the URL server-side and store in the generated HTML using an HTML5 data attribute, eg: (Razor syntax)
我这样做的方法是使用HTML5 数据属性生成 URL 服务器端并存储在生成的 HTML 中,例如:(Razor 语法)
<li class='customClass' data-url='@Url.Action("DisplayItems", "Home", new { id = Model.Id })'>...</li>
Then you can use the jQuery attr() function to pick up the url, eg:
然后你可以使用 jQuery attr() 函数来获取 url,例如:
$(".customClass").click(function () {
$.ajax({
url: $(this).attr("data-url"),
success: function (data) {
// do stuff
}
});
});
If you're generating HTML client-side in response to AJAX calls, you can include the relevant URLs in your JSON payload and populate the data-attribute the same way.
如果您正在生成 HTML 客户端以响应 AJAX 调用,您可以在 JSON 有效负载中包含相关的 URL,并以相同的方式填充data-属性。
回答by tvanfosson
Wrap the AJAX call in a function that takes the URL (and any other data) as a parameter(s) and returns the response. Then in your view, call the function instead of calling the AJAX call directly.
将 AJAX 调用包装在一个函数中,该函数将 URL(和任何其他数据)作为参数并返回响应。然后在你的视图中,调用函数而不是直接调用 AJAX 调用。
function doAjax( url, data, elem, callback )
{
return $.ajax({
url: url,
data: { ajax: data },
cache: false,
success: function(response) { callback(response, elem, xhr); }
});
}
...
<input type='button' value='Go get it' onclick='doAjax( <%= Url.Action ...
I'm not sure that this is any better than having the Ajax call on the page instead of in a JS file, unless you use the exact same pattern frequently.
我不确定这是否比在页面上而不是在 JS 文件中调用 Ajax 更好,除非您经常使用完全相同的模式。
回答by Kyle Nunery
Use the module pattern.
使用模块模式。
// separate js file
var PAGE_MODULE = (function () {
var url = {},
init = function(url) { ... },
load = function() {
$.ajax({
url: url,
...
});
}
return { init: init };
})();
// calling init goes on the page itself
PAGE_MODULE.init(" %: Url.Action(...) %>");
In general the inline onclick handler is not good javascript as you are using a global function.
一般来说,内联 onclick 处理程序不是好的 javascript,因为您使用的是全局函数。
onclick='doAjax(
I recommend reading http://jqfundamentals.com/book/index.html#N20D82to get a better handle on the module pattern.
我建议阅读http://jqfundamentals.com/book/index.html#N20D82以更好地处理模块模式。
回答by stusmith
Here's another way:
这是另一种方式:
In your master page, include an area for inline scripts:
在您的母版页中,包含一个用于内联脚本的区域:
<head>
...
<asp:ContentPlaceHolder runat="server" ID="_inlineScripts" />
...
</head>
Then in the Page_Load, create a utility function:
然后在 Page_Load 中,创建一个实用函数:
protected void Page_Load( object sender, EventArgs e )
{
AddInlineScript( string.Format( "$.url=function(url){{return '{0}'+url;}}", GetBaseUri() ) );
...
}
private Uri GetBaseUri()
{
var requestUrl = Request.Url.AbsoluteUri;
var i = requestUrl.IndexOf( request.Path );
return new Uri( requestUrl.Substring( 0, i ) );
}
private void AddInlineScript( string content )
{
var script = new HtmlGenericControl( "script" );
script.Attributes.Add( "type", "text/javascript" );
script.InnerHtml = content;
_inlineScripts.Controls.Add( script );
}
Now you can use this function in your ajax:
现在你可以在你的 ajax 中使用这个函数:
$.ajax({
url: $.url('path/to/my-handler'),
...
});