7

のエディタテンプレートを作成したいのですがDateTime、3つの別々のフィールドが必要です。

(DropDown) Day    |    (DropDown) Month    |    (DropDown) Year

このファイルはどこでどのように作成しますか?DateTimeそして、コントローラーに投稿するときに、これら3つのフィールドを1つに変換するには、何をする必要がありますか?

4

5 に答える 5

3

Scott Hanselmanは、を処理するカスタムモデルバインダーの作成に関するブログ投稿DateTimeをしています。それはあなたのシナリオに正確には適合しませんが、それはあなたにいくつかのアイデアを与えるはずです、そしてそれが配置されると、エディターテンプレートははるかに簡単になるはずです...

作成されたファイルをどこに配置するかという点では、これは簡単なことです。

~/Views/Shared/EditorTemplates/DateTime.[ascx|cshtml|vbhtml]
于 2011-07-14T13:00:44.740 に答える
3

Views/Shared/EditorTemplatesフォルダに という部分ビューを作成しますDateTime.ascx

この EditorTemplate のコードは次のようになります。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<DateTime?>" %>

<%
    string controlId = ViewData.TemplateInfo.HtmlFieldPrefix.Replace('.', '_');
%>

<script type="text/javascript">
$(function () {
    $('#<%: controlId %>_Day, #<%: controlId %>_Month, #<%: controlId %>_Year').live('change', function () { updateHiddenDate('<%: controlId %>'); });
    $('#<%: controlId %>_Day').val('<%: Model.HasValue ? Model.Value.Day.ToString() : "" %>');
    $('#<%: controlId %>_Month').val('<%: Model.HasValue ? Model.Value.Month.ToString() : "" %>');
    $('#<%: controlId %>_Year').val('<%: Model.HasValue ? Model.Value.Year.ToString() : "" %>');
    updateHiddenDate('<%: controlId %>');
});

function updateHiddenDate(hiddenDateId) {
    $('#' + hiddenDateId).val($('#' + hiddenDateId + '_Year').val() + "-" + $('#' + hiddenDateId + '_Month').val() + "-" + $('#' + hiddenDateId + '_Day').val());
}
</script>

<select id="<%: controlId %>_Day">
<%  for (int dayOrdinal = 1; dayOrdinal <= 31; dayOrdinal++)
    {
        Response.Write(string.Format("<option value=\"{0}\">{0}</option>", dayOrdinal));
    }
%>
</select>
<select id="<%: controlId %>_Month">
<%  for (int monthOrdinal = 1; monthOrdinal <= 12; monthOrdinal++)
    {
        Response.Write(string.Format("<option value=\"{0}\">{1}</option>", monthOrdinal, System.Globalization.DateTimeFormatInfo.CurrentInfo.MonthNames[monthOrdinal - 1]));
    }
%>
</select>
<select id="<%: controlId %>_Year">
<%  for (int yearOrdinal = DateTime.Now.Year - 5; yearOrdinal <= DateTime.Now.Year + 5; yearOrdinal++)
    {
        Response.Write(string.Format("<option value=\"{0}\">{0}</option>", yearOrdinal));
    }
%>
</select>

<%: Html.Hidden("", Model.HasValue ? String.Format("{0:yyyy-MM-dd}", Model) : "") %>

これにより、MVC ModelBinder が解析できる日付の ISO 8601 表現を含む隠しフィールドを持つエディター テンプレートが作成されます。

ドロップダウンが変更されるたびに、jQuery は隠しフィールドを更新します。隠しフィールドViewData.TemplateInfo.HtmlFieldPrefixの生成を取得するために使用するの使用に注意してください。id

完全な日時を含む単一のフォーム値を作成するため、このソリューションはカスタム ModelBinders をいじることなく簡単に導入できることに注意してください。ただし、これは次のことを意味します。

  1. JavaScript が有効になっているクライアントに依存している。
  2. マスターページに jQuery ライブラリへのスクリプト参照を含める必要があります (例: <script type="text/javascript" src="../../Scripts/jquery-1.4.1.min.js"></script>)

それが受け入れられない場合は、@Jon が指摘したようにカスタム ModelBinders を確認する必要があります。

于 2011-07-14T13:45:12.190 に答える
1

エディターテンプレートが最善の策です。エディターテンプレートをどこからでも利用できるようにする場合は、Views / Shared/EditorTemplatesフォルダーに配置します。すべてのDateTimeタイプでこのテンプレートを使用する場合は、と呼ばれるパーシャルを作成しますDateTime。一部の人だけにこのテンプレートを使用させたい場合は、それを別の名前で呼び出し、UIHintAttribute属性を使用して、その属性に使用する値と同じ名前のエディターテンプレートを作成します。

モデルバインダーを引き続き機能させるには、エディターにJavaScriptを追加する必要がある場合があります。ドロップダウンのいずれかを変更すると、選択した月/日で非表示フィールド(モデルバインダーが機能するように正しい名前)が更新されます。 /年の値。

于 2011-07-14T13:00:14.833 に答える
0

intsおそらく最も効率的ではありませんが、ビューモデルでは、日、月、年にそれぞれ3つ持つことができます。次に、送信されたビューモデルを返すときに、3つのフィールドを使用してDateTimeオブジェクトを作成できます。

テンプレートを作成する限り、部分的なビューが最善の方法だと思います。よくわかりませんが、私はまだMVCを自分で学んでいます。

于 2011-07-14T12:54:03.570 に答える
0

html.editorfor を使用している場合は、views/shared/Editors にコントロールを定義する ascx ファイルを追加することで、独自のエディターを指定できます。3 つのフィールドの追加は、そのファイルのコード ビハインドで行われます。

于 2011-07-14T13:02:26.093 に答える