2

現在、大きなWebFormsアプリをMVCに転送中です。

WebFormsアプリには、再利用可能なコントロールがいくつかあります(.ascx)。たとえば、入力時にユーザー名の候補を表示するTextBox。このコントロールは、ページにJS / CSSを追加し、サーバー側のロジックとカスタムプロパティ(などSelectedUserID)を備えています。

MVCアプリには何を含める必要がありますか?それらをMVCアプリの1つの再利用可能なエンティティにカプセル化するにはどうすればよいですか?多分部分的なビュー?しかし、たとえば、部分ビューからページにJS / CSSを追加することはできません(できれば、まだ追加されていないことを確認してください)...また、部分ビューで<head>上記のようなものを返すにはどうすればよいですか?SelectedUserID

質問を言い換えると、MVCアプリにそのようなコントロールをどのように実装しますか?

PS。MVCアプリで.ascxユーザーコントロールを引き続き使用できることは知っていますが、これは「ハッキー/レガシー」な方法のようです。「正当な」オプションとは何ですか?

4

6 に答える 6

4

あなたの質問はかなり広いです。私のコメント/回答はすべてRazorにあります。私の意見では、MVCに切り替える場合は、Razorを使用することをお勧めします。切り替える理由はたくさんありますが、移行する人にとっては私の一番の選択だと思います。最良の理由は2つあります。最初のかみそりは、プログラミングがWebフォームでどのように機能するかについていくつかの悪い習慣を捨てることを可能にし、同じ方法で、元のコードをコピーして貼り付けてMVCで機能するように変更する代わりに、コードを書き直すことを余儀なくされました。

このコントロールは、ページにJS / CSSを追加し、サーバー側のロジックとカスタムプロパティをいくつか備えています。MVCアプリには何を含める必要がありますか?

これはかなり宗教的なソフトウェアの質問です。それを行う方法はたくさんあります。

それで、MVCにJS/CSSを追加する方法についての私の宗教的な意見に。サーバー側を含める1つの方法は、レイアウト/マスターテンプレートにリージョンを作成することです。

ビュー/_ViewStart.cshtml

@{
  Layout = "~/Views/Shared/Layout.cshtml";
}

Views / Shared / Layout.cshtml

<!doctype html>
  <head>
    <link href="/Styles/Global.css" rel="stylesheet" type="text/css" />
    @RenderSection("Styles", required: false)
    <script src="/Scripts/Global.js" type="text/javascript"></script>
    @RenderSection("Scritps", required: false)

これにより、各ビューrequired=falseでRenderSecionコードを使用してスタイルまたはスクリプトをオプションで追加できるようになります。

Views / Home / Index.cshtml

@section Styles {
    <link href="/Styles/Home/Index.css" rel="stylesheet" type="text/css" />
}

これは非常に単純であり、多くの単純なサイトから中程度に複雑なサイトにおそらく適したソリューションです。私はあなたが要求したことをする必要があり、本当に必要な場合にのみファイルを含める必要があったので、これは私にとって十分ではありませんでした。さらに、部分的なビューとテンプレートはセクションをレンダリングできません。これは巨大なPITAであることがわかりました。そこで、HtmlHelper拡張メソッドをいくつか追加しました。(スタイルシートはほぼ同一のコードであるため、Javascriptのコードのみを表示します。これらのメソッドは重複するURLを許可しません。

Domain / HtmlHelperExtensions.cshtml

public static class HtmlHelperExtensions
{
    private const string _JSViewDataName = "RenderJavaScript";
    private const string _StyleViewDataName = "RenderStyle";

    public static void AddJavaScript(this HtmlHelper HtmlHelper, string ScriptURL)
    {
        List<string> scriptList = HtmlHelper.ViewContext.HttpContext.Items[HtmlHelperExtensions._JSViewDataName] as List<string>;
        if (scriptList != null)
        {
            if (!scriptList.Contains(ScriptURL))
            {
                scriptList.Add(ScriptURL);
            }
        }
        else
        {
            scriptList = new List<string>();
            scriptList.Add(ScriptURL);
            HtmlHelper.ViewContext.HttpContext.Items.Add(HtmlHelperExtensions._JSViewDataName, scriptList);
        }
    }

    public static MvcHtmlString RenderJavaScripts(this HtmlHelper HtmlHelper)
    {
        StringBuilder result = new StringBuilder();

        List<string> scriptList = HtmlHelper.ViewContext.HttpContext.Items[HtmlHelperExtensions._JSViewDataName] as List<string>;
        if (scriptList != null)
        {
            foreach (string script in scriptList)
            {
                result.AppendLine(string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>", script));
            }
        }

        return MvcHtmlString.Create(result.ToString());
    }
}

更新されたViews/Shared / Layout.cshtml

<!doctype html>
  <head>
    <link href="/Styles/Global.css" rel="stylesheet" type="text/css" />
    @Html.RenderStyleSheets()
    <script src="/Scripts/Global.js" type="text/javascript"></script>
    @Html.RenderJavascripts()

更新されたViews/Home / Index.cshtml

@Html.AddStyleSheet("/Styles/Home/Index.css")

次の質問に...

それらをMVCアプリの1つの再利用可能なエンティティにカプセル化するにはどうすればよいですか?多分部分的なビュー?

Razorは、部分ビューとテンプレートの両方をサポートしています。技術的には、それぞれが実行できることには大きな重複がありますが、プログラマーが必要なときにそれぞれを利用できるようにそれぞれを設計する方法には制限があります。

部分ビューは、レンダリングするためにモデル/クラスを必要としません。これが完全に有効な部分ビューです。

/Views/Home/Index.cshtml

@Html.Partial("Partial-Menu")

/Views/Shared/Partial-Menu.cshtml

<div id="menu">
  <a href="/">Home</a>
  <a href="/Home/About">About Us</a>
</div>

もう一方のテンプレートには、レンダリングするためにモデルが必要でした。これは、テンプレートが任意のクラスまたは構造体を編集テンプレートまたは表示テンプレートとしてレンダリングする方法であるためです。

/Models/Person.cs

public class Person
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
}

/Controllers/HomeController.cs

public ActionResult Index()
{
  Person model = new Person();
  model.FirstName = "Jon";
  model.LastName = "Doe";

  return this.View(model);
}

/Views/Home/Index.cshtml

@model Project1.Models.Person

@Html.DisplayModel()

@Html.EditforModel()

/Views/Shared/DisplayTemplates/Person.cshtml

@model Project1.Models.Person

<div>@Html.LabelFor(x => x.FirstName) @Html.DisplayFor(x => x.FirstName)</div>
<div>@Html.LabelFor(x => x.LastName) @Html.DisplayFor(x => x.LastName)</div>

/Views/Shared/EditorTemplates/Person.cshtml

@model Project1.Models.Person

<div>@Html.LabelFor(x => x.FirstName) @Html.EditorFor(x => x.FirstName)</div>
<div>@Html.LabelFor(x => x.LastName) @Html.EditrorFor(x => x.LastName)</div>

私の見方では、データ入力用のフォームに変わる可能性のあるモデルは、おそらくテンプレートである必要があります。これは、モデルをカプセル化する方法です。以前に提供された拡張メソッドを使用すると、必要に応じて部分ビューとテンプレートの両方にインクルードをロードできます(現在、これを使用するために実際に必要なのは、それらのモデルの1つだけです)。

私の好みは、レンダリングされるページごとに(各Javascriptとスタイルの)最大3つのインクルードを持つことです。私は基本的にGlobal.css/js、コントローラーHome.css / js、そして可能な限りページIndex.css/jsを持っています。コントローラーを含めることはめったにありません。

于 2012-05-31T18:26:55.280 に答える
4

私がこれまでに見つけた最善の解決策は、Razor宣言型ヘルパーです。彼らは素晴らしくフィットします。

@helper UserTextBox() {
    <input type="text" />

    <!--my own helper that registers scripts-->
    @Html.AddJS("../js/myscript.js") 
}

関連する質問:Razor:宣言型HTMLヘルパー

関連するメモ:宣言型ヘルパー内で@Htmlヘルパーを使用することはできませんが、回避策があります:https ://stackoverflow.com/a/5557503/56621

于 2012-06-03T17:27:19.133 に答える
1

ええと、「自動的に」css/jsを含むものを持つことはできません。これは、ユーザーがページ(マスター/レイアウトまたは現在のページ)に追加する必要があるものです。ただし、一般的には、Htmlヘルパーを作成します。これらが複雑なシステム(asp.net時代の巨大なグリッドのような)であると期待しないでください、しかしあなたはそれらで多くをすることができます。

はい、部分的なページは単純なものの方が簡単かもしれません。さらに単純なのは、エディターまたは表示テンプレートです。

ただし、一般的に、最近のMVCのほとんどの「コントロール」はjQueryベースです。

短いビデオはこちらから入手できます:http ://www.asp.net/mvc/videos/mvc-2/how-do-i/how-do-i-create-a-custom-html-helper-for-an -mvc-application

これらのメカニズムにJavaScriptを含めたくはありません。単一のコントロールで機能する場合もありますが、ページに複数のコントロールがある場合は、css/jsが重複します。

于 2012-05-30T20:27:18.877 に答える
1

js / cssをメインレイアウトに追加してから、カスタムコントロールをレンダリングするためのhtmlヘルパーを作成します。

aspnetmvcでjqueryを使用する多くのコントロールはこのように機能します。

ここでこのコントロールを見てください

于 2012-05-30T22:50:40.877 に答える
0

1)カスタムjs / cssの場合、次のようなセクションを使用できます。

//ビュー内のコード

@section someName
{
    ...
}

//レイアウトページのコード

@if (IsSectionDefined("someName"))
    {
        @RenderSection("someName")
    }

2)私は次のことをしたほうがいいです:

  • Idプロパティを使用してモデルSelectedUserを作成します
  • このモデルのテンプレートを作成する
  • SelectedUserオブジェクトをそれを必要とする任意のモデルに追加します
于 2012-05-31T05:53:33.260 に答える
0

それらは空白行で周囲のテキストから分離する必要があります。最も外側のブロック要素の開始タグと終了タグをインデントしないでください。マークダウンはHTMLブロック内では使用できません。

于 2017-03-16T12:18:42.200 に答える