web-dev-qa-db-ja.com

ASP.NET MVC / Razorで、「コントロール」にイニシャライザJavaScriptを追加する方法は?

実際、私は問題に対して少なくとも3つの異なる解決策を既に持っていますが、さまざまな理由でそれらのどれも好きではありません。

ASP.NET MVC/Razorには、ASP.NETの場合のようなコントロールはありません。 ASCXコントロールは以前はビュー+コントローラーが絡み合っていたので、取得しました。代わりに、文字列、htmlフラグメントを出力するhtmlヘルパーがあります。 jQuery UI日付ピッカーを作成するライブラリーにヘルパーメソッドを作成するとします。

最初のソリューション。最初にテキストボックスを作成するメソッド(実際にはTextBoxForを呼び出すこともできます。これは私にとって同じことを行うためです)を記述し、次に$('#textboxid').datepicker()を呼び出す小さなJavaScriptコードフラグメントを作成します。次に、Razorビューでそれを呼び出すことができます。ビュー関連のことはRazorではなくコードで行われるのが嫌いですが、すべてのデフォルトのエディターテンプレートは残念ながらそのようなものです。出力htmlの各テキストボックスの後に小さなスクリプトフラグメントがたくさんあるのが好きではありません。そして、私のコードフラグメントは複雑になる可能性があり、そのイニシャライザJSに多くのパラメータがある場合、見苦しくなり、文字列のエスケープの問題などが発生します.

マイクロソフトは控えめなJavaScriptアーキテクチャを推進しています。テキストボックスにCSSマーカークラスを配置し、必要に応じていくつかのデータ属性を追加し、CSSマーカークラスに基づいて、すべてのテキストボックスを日付ピッカーに変換するJavaScriptを1つだけ出力できます。この最後の部分が主な問題です。それを行うには、命令型JSコードが必要です。控えめなAJAXと検証はうまく機能します。必要がないため、ユーザーインタラクションイベントに応答するだけです。これは当てはまりません。テキストボックスを日付ピッカーに変換する必要があるときはいつでもそして、それらは編集可能なグリッドに動的に、またはAJAX呼び出しの後で、いつでも表示できます。

3番目の解決策は、Razorで表示する必要があるため、Razorで編集テンプレートとして実行してみましょう。問題は、ここでクラスライブラリについて話していることです。過去に、.cshtmlファイルを埋め込みリソースとして埋め込む、またはコンパイル中に実際のC#コードにコンパイルするための醜いハッキングを見てきました。最後に確認したところ、それらは醜いハックのように見え、サポートされていませんでした。

別の解決策はありますか?そうでない場合、上記のうち最も優れたもの、最先端のコーディング規約、またはMicrosoftのアイデアなどに最も準拠しているものはどれですか。

5
fejesjoco

適切な問題を特定したかどうかは完全にはわかりませんが、問題がある場合は、これが役立つことがあります。

ScriptManagerというクラスを作成しました。これにより、レンダリングされたときにすべてのページの下部に任意のJavaScriptファイルや関数を追加できます。これを試してみてください:

public class ScriptManager
{
    public List<string> scripts = new List<string>();
    public List<string> scriptFiles = new List<string>();
}
public static class HtmlExtensions
{

    [ThreadStatic]
    private static ControllerBase pageDataController;
    [ThreadStatic]
    private static ScriptManager pageData;

    public static ScriptManager ScriptManager(this HtmlHelper html)
    {
        ControllerBase controller = html.ViewContext.Controller;

        // This makes sure we get the top-most controller
        while (controller.ControllerContext.IsChildAction)
        {
            controller = controller.ControllerContext.ParentActionViewContext.Controller;
        }
        if (pageDataController == controller)
        {
            // We've been here before
            return pageData;
        }
        else
        {
            // Initial setup
            pageDataController = controller;
            pageData = new ScriptManager();
            return pageData;
        }
    }
}

次に、_Layout.cshtmlページ:

@foreach (var script in Html.ScriptManager().scriptFiles.Distinct())
{
    @Html.Script(script);
}
@foreach (var script in Html.ScriptManager().scripts)
{
    @Html.Raw("<script type='text/javascript'>")
    @Html.Raw(script)
    @Html.Raw("</script>")
}

最後に、次のような部分的なビューで使用します。

@{
  Html.ScriptManager().scriptFiles.Add(Url.Content("~/Scripts/jquery.blockUI.js"));
 }

ページのヘッダーにあるスクリプトについてクライアントに伝える機能は失われますが、(たとえば)blockUIを使用する部分ビューを使用するすべてのページに含まれます。

5
Bobson

もう1つは、cshtmlと対応するコントローラーを下に置くことです。このようなものをコントロールと呼び、@Html.RenderPartial('<action_url>', <model>)を使用して別のビューに埋め込みます。コントローラでは、アクションを[ChildActionOnly]属性で注釈を付けて、直接呼び出しで呼び出せないようにする必要があります。

私がそのアプローチの大ファンではないので、ここで説明して、全体像を把握してください。

@helperヘルパーに加えて、Razorの@Html.を使用することもできます。

0
SOReader