web-dev-qa-db-ja.com

ASP.NETMVCを使用してJSファイルでjQueryのajaxURLを設定する

MVCアクションに対してAjax呼び出しを実行すると、現在、JavaScriptが独自のJSファイル内ではなく、ビュー内にあります。

そうすれば、これを行うのは非常に簡単です。

_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) }
});
_

...その後、JS内でUrl.Action()を使用してajax呼び出しにURLを含めるのは非常に簡単です。 URLをハードコーディングせずに、これを独自のJSファイルに移動するにはどうすればよいですか?

21
Schotime

この方法ではMVCルーティングを完全に使用するため、MVCフレームワークを十分に活用できます。研究者の答えに触発されました。

ここでは、このURLの動的JavaScriptに対してApplicationControllerにアクションがあります。

 /application/js

マスターJavaScriptファイルを1つだけダウンロードしたいので、ここに静的ファイルを含めています。必要に応じて、動的なものを返すことを選択できます。

     /// <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"
        };
    }

これは、ルックアップテーブルを作成するヘルパー関数です。使用するRouteUrlごとに1行追加するだけです。

    [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();
    }

これにより、次の動的JavaScriptが生成されます。これは基本的に、任意のキーからアクションメソッドに必要なURLへのルックアップテーブルです。

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

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;

};

私はそれをどこからでも呼び出すことができます:

 RRStore.updateCart(1001, 5);

これが、ルーティングをクリーンな方法で使用できるようにする唯一の方法のように思われました。 javascriptでURLを動的に作成するのは面倒で、テストが困難です。テストタイプは、ここのどこかにレイヤーを追加して、テストを簡単に容易にすることができます。

19
Simon_Weaver

私のやり方は、サーバー側でURLを生成し、 HTML5データ属性 を使用して生成されたHTMLに格納することです。例:(レイザー構文)

<li class='customClass' data-url='@Url.Action("DisplayItems", "Home", new { id = Model.Id })'>...</li>

次に、jQuery attr()関数を使用してURLを取得できます。例:

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

AJAX呼び出しに応答してHTMLクライアント側を生成している場合は、関連するURLをJSONペイロードに含めて、data-同じ方法で属性を設定します。

34
Sam

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 ...

まったく同じパターンを頻繁に使用しない限り、これがJSファイルではなくページでAjax呼び出しを行うよりも優れているかどうかはわかりません。

6
tvanfosson

モジュールパターンを使用します。


// 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(...) %>");

一般に、インラインonclickハンドラーは、グローバル関数を使用しているため、適切なJavaScriptではありません。

 
 onclick = 'doAjax(

モジュールパターンをより適切に処理するには、 http://jqfundamentals.com/book/index.html#N20D82 を読むことをお勧めします。

3
Kyle Nunery