3

関連する質問:

ユーザーが追加できるアイテムのコレクションをレンダリングする ASP.NET MVC ビューがあります。

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MySite.Models.Parent>" %>
<% using (Html.BeginForm()) { %>
    <%: Html.ValidationSummary(true) %>
    <%: Html.HiddenFor(model => model.Id) %>
    <table>
        <thead>
            <tr>
                ...
                <th>Value</th>
            </tr>
        </thead>
        <tbody>
            <% foreach (var child in Model.Children)
               {
                   Html.RenderPartial("ChildRow", child );
               } %>
        </tbody>
    </table>
    <p>
        <input type="submit" value="Save" />
        <%= Html.ActionLink<MyController>(x => x.ChildRow(), "Add another...", new { @class = "addRow" }) %>
    </p>
<% } %>

「ChildRow」パーシャルは次のとおりです。

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MySite.Models.Child>" %>
<tr class="editor-row">
    <td>
        <%  Html.EnableClientValidation(true);
            using (Html.BeginCollectionItem("Children")) { %>
        <%: Html.HiddenFor(model => model.Id)%>
    </td>
    <td>
        <%: Html.EditorFor(model => model.Value)%>
        <%: Html.ValidationMessageFor(model => model.Value)%>
        <% } %>
    </td>
</tr>

行を表す部分を取得するために jQuery を使用しています:-

$("a.addRow").live("click", function () {
    $.ajax({
        url: this.href,
        cache: false,
        success: function (html) {
            $(this).parents("form:first").children("table:first tbody:last").append(html);
            $.validator.unobtrusive.parse("form");
        }
    });
    return false;
});

私が抱えている問題は、jQuery によって追加された行に対してクライアント側の検証が機能しないことです。私のスクリプトからわかるように、ajax 呼び出しの後にフォームに対してバリデーターを実行しています。私が見回す限り、問題は Html.BeginForm() 呼び出しが ajax パーシャルにないため、検証属性が入力要素に追加されていないことです。つまり、行を追加した後にマークアップを表示した場合:-

ページの読み込み時に存在する入力は次のようになります:-

<input name="Children[0a197c09-470c-4ab4-9eef-2bcc5f0df805].Value"
  class="text-box single-line" id="Children_0a197c09-470c-4ab4-9eef-2bcc5f0df805__Value"
  type="text" data-val-required="The Value field is required." data-val="true" value="Test"/>

ajax 経由で追加された入力は次のようになります。

<input name="Children[aa5a21b2-90bc-4e06-aadc-1f2032a121aa].Value"
  class="text-box single-line" id="Children_aa5a21b2-90bc-4e06-aadc-1f2032a121aa__Value"
  type="text" value=""/>

明らかに、フォームの性質上、Html.BeginForm 呼び出しを部分ビューに移動することはできません。ページが ajax 経由で読み込まれているため、パーシャルの FormContext をハックすることもできません。

クライアント側の検証を有効にする別の方法はありますか?

編集

以下のカウンセラーベンの回答に従って、FormContext を設定すると、属性が正しくレンダリングされるようになりましたが、検証はまだ機能していません (新しい行を追加してテキスト ボックスを空白のままにした場合、アプリケーションが最初に気付くのは、 Edit POST アクションがヒットします)。

私はいくつかのテストを行い、 $.validator.unobtrusive.parse 関数が確実に呼び出され、parseElement 関数が確実にテーブル内の新しい入力数に対して正しい回数呼び出され、行 "info.attachValidation( );」さらに下の解析関数は間違いなくヒットしています。それは私が持っている限りです。まだテスト中です。

4

3 に答える 3

8

発生している問題は、サーバーが新しい行を作成しているときに FormContext が存在しないことです。控えめな検証属性を生成された HTML に追加するには、FormContext が存在する必要があります。部分ビューの先頭に次を追加します。

if (this.ViewContext.FormContext == null) 
{
    this.ViewContext.FormContext = new FormContext(); 
}

カウンセラーベン

于 2011-08-10T18:41:20.340 に答える
4

私の質問の2番目の部分への回答として、明らかに、フォームでjquery.validate.unobtrusive.parseを2回呼び出すことはできません。フォームにすでにバリデーターがある場合、それは置き換えられません。

彼のビットははるかに難しいビットだったので、カウンセラーベンに受け入れられた答えを与えるつもりです:D

編集

ああ、私もそれを最初に見つけたわけではないようです:

http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/

于 2011-08-10T19:42:15.310 に答える