4

生成された要素の HTML 属性「ID」を取得し、ASP.NET Web フォーム Field.ClientID にリンクする可能性があるかどうか疑問に思っています。

だから私が達成しようとしているのは、JavaScript で id を取得することです。現在、フォームバリデーターに取り組んでいるので、

RAZOR テンプレート

@Html.TextEditorFor(m => m.aspnet_Membership.Email);

次に検証用のJS

$('#MyForm').validate({
   rules : {
      //and this is the part where I need email ID
      //I can do this by manually typing aspnet_Membership_Email
      //but I'm asking is there a way to get it like 
      @Html.GetElementID(m => m.aspnet_Membership.Email): {
        required: true,
        email: true
     }
   }
});

多くのフィールドがあるので、apsnet のようなユーザー入力エラーを避けるためにこれが必要です.....

JS はテンプレートにあることに注意してください。外部jsファイルにはありません。(私は初心者ではありません:))

Validator だけに注目しないでください。例として追加しました。ページに一意の ID を持たせるためにフォームの各フィールドに将来のプレフィックスを追加すると、フィールド ID が固定されている場合に js を修正するなどの問題が発生します。

前もって感謝します。

4

4 に答える 4

2

ヘルパーIdForは、このタスクに役立ちます。

@html.IdFor(m => m.aspnet_Membership.Email)
于 2012-11-27T19:15:57.670 に答える
1

独自の拡張メソッドを作成します。

public static class Helper
{
    public static MvcHtmlString GetElementID<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
    {
        return MvcHtmlString.Create(GetPropertyName(expression));
    }

    private static string GetPropertyName(Expression lambdaExpression)
    {
        IList<string> list = new List<string>();
        var e = lambdaExpression;

        while (true)
        {
            switch (e.NodeType)
            {
                case ExpressionType.Lambda:
                    e = ((LambdaExpression)e).Body;
                    break;
                case ExpressionType.MemberAccess:
                    var propertyInfo = ((MemberExpression)e).Member as PropertyInfo;
                    var prop = propertyInfo != null
                                      ? propertyInfo.Name
                                      : null;
                    list.Add(prop);

                    var memberExpression = (MemberExpression)e;
                    if (memberExpression.Expression.NodeType != ExpressionType.Parameter)
                    {
                        var parameter = GetParameterExpression(memberExpression.Expression);
                        if (parameter != null)
                        {
                            e = Expression.Lambda(memberExpression.Expression, parameter);
                            break;
                        }
                    }
                    return string.Join("_", list.Reverse());
                default:
                    return null;
            }
        }
    }

    private static ParameterExpression GetParameterExpression(Expression expression)
    {
        while (expression.NodeType == ExpressionType.MemberAccess)
        {
            expression = ((MemberExpression)expression).Expression;
        }
        return expression.NodeType == ExpressionType.Parameter ? (ParameterExpression)expression : null;
    }
}

およびaspnet_Membership_Emailになる使用方法:

@Html.GetElementID(m => m.aspnet_Membership.Email);

これにより、ラムダ式に基づいて連結されたプロパティ チェーンが得られます。基本的には@Html.IdForMVC4 の実装に似ています (ただし、実装は確認していません)。

于 2012-11-27T19:27:09.447 に答える
0

比較的単純ですが、ID 生成ロジックをカプセル化するのは正しいと思います。あなたの Html ヘルパーのアイデアは、それを行うための効率的な方法のように思えます (モデル内のフィールド値とともに一連の ID 値を公開するのではなく)。

しかし、目立たない検証機能を使用せず、バリデーターを生成させない理由が気になります。

[Required] 属性を Email プロパティに追加し、目立たないバリデータ JavaScript をページに含めると、今ではピニャコラーダを飲んでいるでしょう。

あなたのモデルでは:

[Required]
[Display(Name = "First Name")]
[RegularExpression("([\r-~])*", ErrorMessageResourceType = typeof (AccountMessages),
    ErrorMessageResourceName = "FormFieldInvalid")]
[StringLength(50)]
public string FirstName { get; set; }

マークアップで:

@Html.LabelFor(model => model.User.FirstName)
@Html.TextBoxFor(model => model.User.FirstName)  
@Html.ValidationMessageFor(model => model.User.FirstName, null, new { @class = "errorMessageField" })
于 2012-11-27T19:15:26.373 に答える
0

フレームワークが名前を作成するために使用するクラス (つまり ID ではありません) は、呼び出される静的クラスExpressionHelperであり、MVC3 でパブリックにアクセスできます。GetExpressionTextラムダを受け取る1 つの関数が呼び出されます。そうは言っても、必要な構文を取得するには、独自の IdFor ラッパーを作成する必要があります。

これは、MVC4 に存在するクラスです。

public static class NameExtensions
{
    public static MvcHtmlString Id(this HtmlHelper html, string name)
    {
        return MvcHtmlString.Create(html.AttributeEncode(html.ViewData.TemplateInfo.GetFullHtmlFieldId(name)));
    }

    [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
    [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
    public static MvcHtmlString IdFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression)
    {
        return Id(html, ExpressionHelper.GetExpressionText(expression));
    }

    public static MvcHtmlString IdForModel(this HtmlHelper html)
    {
        return Id(html, String.Empty);
    }

    [SuppressMessage("Microsoft.Naming", "CA1719:ParameterNamesShouldNotMatchMemberNames", MessageId = "1#", Justification = "This is a shipped API.")]
    public static MvcHtmlString Name(this HtmlHelper html, string name)
    {
        return MvcHtmlString.Create(html.AttributeEncode(html.ViewData.TemplateInfo.GetFullHtmlFieldName(name)));
    }

    [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
    [SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
    public static MvcHtmlString NameFor<TModel, TProperty>(this HtmlHelper<TModel> html, Expression<Func<TModel, TProperty>> expression)
    {
        return Name(html, ExpressionHelper.GetExpressionText(expression));
    }

    public static MvcHtmlString NameForModel(this HtmlHelper html)
    {
        return Name(html, String.Empty);
    }
}
于 2012-11-27T19:27:50.347 に答える