Définition de l’URL ajax pour jQuery dans un fichier JS à l’aide de ASP.NET MVC

Lorsque je fais un appel Ajax à une action MVC, javascript est inséré dans la vue, pas dans son propre fichier JS.

Il est alors très facile de faire ceci:

var xhr = $.ajax({ url: '/' + el1.siblings("input:hidden").val(), data: { ajax: "Y" }, cache: false, success: function(response) { displayMore(response, el1, xhr) } }); 

… puis inclure l’URL dans l’appel ajax en utilisant Url.Action() à l’intérieur du JS est assez facile. Comment pourrais-je déplacer cela faire son propre fichier JS sans coder en dur l’URL?

De cette manière, vous utilisez pleinement le routage MVC afin que vous puissiez pleinement tirer parti du framework MVC. Inspiré par la réponse de Stusmith.

Ici, j’ai une action dans ApplicationController pour le javascript dynamic pour cette URL:

  /application/js 

J’inclus les fichiers statiques ici parce que je ne souhaite télécharger qu’un seul fichier maître javascript. Vous pouvez choisir de simplement renvoyer le contenu dynamic si vous voulez:

  ///  /// Renders out javascript ///  ///  [OutputCache(CacheProfile = "Script")] [ActionName("js")] public ContentResult RenderJavascript() { SsortingngBuilder js = new SsortingngBuilder(); // 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.ToSsortingng(), ContentType = "application/x-javascript" }; } 

C’est la fonction d’assistance qui crée notre table de consultation. Ajoutez simplement une ligne pour chaque RouteUrl que vous souhaitez utiliser.

  [NonAction] private ssortingng GetLookupTables() { SsortingngBuilder js = new SsortingngBuilder(); // 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.ToSsortingng(); } 

Cela génère le javascript dynamic suivant, qui est essentiellement une table de recherche d’une clé arbitraire à l’URL dont j’ai besoin pour ma méthode d’action:

 // URL Lookuptable $.url=function(url) { var lookupTable = {"updateCart":"/rrmvc/store/cart/updatecart","removeItem":"/rrmvc/store/cart/removeitem"}; return lookupTable[url]; } 

Dans cart.js, je peux avoir une fonction comme celle-ci. Notez que le paramètre url provient de la table de recherche:

  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; 

};

Je peux l’appeler de n’importe où avec juste:

  RRStore.updateCart(1001, 5); 

Cela semblait être le seul moyen que je pouvais trouver qui me permettrait d’utiliser le routage de manière propre. Créer dynamicment des URL en javascript est difficile et difficile à tester. Les types de test peuvent append une couche quelque part ici pour faciliter les tests.

Pour ce faire, je génère l’URL côté serveur et le stocke dans le code HTML généré à l’aide d’un atsortingbut de données HTML5 , par exemple: (syntaxe Razor)

 
  • ...
  • Ensuite, vous pouvez utiliser la fonction jQuery attr () pour récupérer l’url, par exemple:

     $(".customClass").click(function () { $.ajax({ url: $(this).attr("data-url"), success: function (data) { // do stuff } }); }); 

    Si vous générez du côté client HTML en réponse à des appels AJAX, vous pouvez inclure les URL pertinentes dans votre charge utile JSON et renseigner l’atsortingbut data de la même manière.

    Emballez l’appel AJAX dans une fonction qui prend l’URL (et toutes les autres données) en tant que paramètre et renvoie la réponse. Ensuite, dans votre vue, appelez la fonction au lieu d’appeler directement l’appel AJAX.

     function doAjax( url, data, elem, callback ) { return $.ajax({ url: url, data: { ajax: data }, cache: false, success: function(response) { callback(response, elem, xhr); } }); } ... 
    

    Utilisez le modèle de module.

    // separate js file var PAGE_MODULE = (function () { var url = {}, init = function(url) { ... }, load = function() { $.ajax({ url: url, ... }); } return { init: init }; })();
    // 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(...) %>");
    // calling init goes on the page itself PAGE_MODULE.init(" %: Url.Action(...) %>"); 

    En général, le gestionnaire inline onclick n’est pas un bon javascript, car vous utilisez une fonction globale.

    
     onclick = 'doAjax ( 
    

    Je recommande de lire http://jqfundamentals.com/book/index.html#N20D82 pour mieux comprendre le modèle de module.

    Voici un autre moyen:

    Dans votre page maître, incluez une zone pour les scripts en ligne:

      ...  ...  

    Ensuite, dans le Page_Load, créez une fonction utilitaire:

     protected void Page_Load( object sender, EventArgs e ) { AddInlineScript( ssortingng.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.Subssortingng( 0, i ) ); } private void AddInlineScript( ssortingng content ) { var script = new HtmlGenericControl( "script" ); script.Atsortingbutes.Add( "type", "text/javascript" ); script.InnerHtml = content; _inlineScripts.Controls.Add( script ); } 

    Maintenant, vous pouvez utiliser cette fonction dans votre ajax:

     $.ajax({ url: $.url('path/to/my-handler'), ... });