jQuery MVC3 Html.DisplayFor -- 是否可以让这个控件生成一个 ID?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12960623/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 12:10:13  来源:igfitidea点击:

MVC3 Html.DisplayFor -- Is it possible to have this control generate an ID?

jqueryasp.net-mvcasp.net-mvc-3

提问by Sean Anderson

I want to be able to display some text, but also have the text be modifiable via jQuery.

我希望能够显示一些文本,但也可以通过 jQuery 修改文本。

<%= Html.DisplayFor(model => model.DeviceComponentName)%>

If I used EditorFor instead of DisplayFor I would see an ID for the input control. I do not want the value to be editable in that way, though. So, I have made it a DisplayFor, but it does not generate an ID property for the element.

如果我使用 EditorFor 而不是 DisplayFor 我会看到输入控件的 ID。不过,我不希望以这种方式可编辑该值。因此,我已将其设为 DisplayFor,但它不会为该元素生成 ID 属性。

Should I just wrap the DisplayFor in a div and do something like:

我应该将 DisplayFor 包装在一个 div 中并执行以下操作:

<div id="<%= ViewData.TemplateInfo.GetFullHtmlFieldName("DeviceComponentName") %>">
    <%= Html.DisplayFor(model => model.DeviceComponentName)%>
</div>

$('#DeviceComponentName').text('newValue');

Or is there a cleaner way of achieving this?

或者有没有更清洁的方法来实现这一目标?

Update:Is there a way which doesn't depend on hard-coded strings? Something that ties to the object itself so if my property name changes I'd get a compile error?

更新:有没有一种不依赖于硬编码字符串的方法?与对象本身相关的东西,所以如果我的属性名称更改,我会收到编译错误吗?

Also, I am using this code, but I do not see an ID value appear:

另外,我正在使用此代码,但没有看到 ID 值出现:

<td class="editableValue">
    <%--Label should be editable, so it needs an ID, but only will be edited by jQuery so it can't be an EditorFor--%>
    <%= Html.DisplayFor(model => model.DeviceComponentName, new { id = "DeviceComponentName" })%>
    <button type="button" id="ComponentTreeButton" class="nestedDialogButton">...</button>
</td>

回答by naspinski

To avoid 'magic string' inputs (in case your model properties change), you could do this with an extension. It also makes for much cleaner code:

为了避免“魔法字符串”输入(以防您的模型属性发生变化),您可以使用扩展来做到这一点。它还使代码更简洁:

public static MvcHtmlString DisplayWithIdFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string wrapperTag = "div")
{
    var id = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression));
    return MvcHtmlString.Create(string.Format("<{0} id=\"{1}\">{2}</{0}>", wrapperTag, id, helper.DisplayFor(expression)));
}

Then simply use it like this:

然后像这样简单地使用它:

@Html.DisplayWithIdFor(x => x.Name)

Will produce

会产生

<div id="Name">Bill</div>

Or if you want it to be wrapped in a span:

或者,如果您希望将其包裹在一个跨度中:

@Html.DisplayWithIdFor(x => x.Name, "span")

Which will make:

这将使:

<span id="Name">Bill</span>

Non-Razor

非剃须刀

For non Razor syntax, you simply use it like this:

对于非 Razor 语法,您只需像这样使用它:

<%= Html.DisplayWithIdFor(x => x.Name) %>

and:

和:

<%= Html.DisplayWithIdFor(x => x.Name, "span") %>

回答by Xordal

you must be use:

你必须使用:

Html.DisplayFor(model => model.DeviceComponentName, new { @id = "DeviceComponentName"})

For dynamic id and other properties, i use:

对于动态 id 和其他属性,我使用:

Class for metadata:

元数据类:

public class AdditionalHtml : Attribute, IMetadataAware
{
    public string Id { get; set; }

    public string Type { get; set; }

    public string CssClass { get; set; }

    public string PlaceHolder { get; set; }

    public string Style { get; set; }

    public string OnChange { get; set; }

    public int Rows { get; set; }

    public int MaxLength { get; set; }

    public bool ReadOnly { get; set; }

    public bool Disabled { get; set; }

    public Dictionary<string, object> OptionalAttributes ()
    {
        var options = new Dictionary<string, object>();

        if ( !string.IsNullOrWhiteSpace( Id ) )
            options.Add( "id", Id );

        if ( !string.IsNullOrWhiteSpace( Type ) )
            options.Add( "type", Type );

        if ( !string.IsNullOrWhiteSpace( CssClass ) )
            options.Add( "class", CssClass );

        if ( !string.IsNullOrWhiteSpace( PlaceHolder ) )
            options.Add( "placeholder", PlaceHolder );

        if ( !string.IsNullOrWhiteSpace( OnChange ) )
            options.Add( "onchange", OnChange );

        if ( !string.IsNullOrWhiteSpace( Style ) )
            options.Add( "style", Style );

        if ( Rows != 0 )
            options.Add( "rows", Rows );

        if ( MaxLength != 0 )
            options.Add( "maxlength", MaxLength );

        if ( ReadOnly )
            options.Add( "readonly", "readonly" );

        if ( Disabled )
            options.Add( "disabled", "disabled" );

        return options;
    }

Class for metadata provider:

元数据提供者的类:

public class MetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata ( IEnumerable<Attribute> attributes, Type containerType, Func<object> modelAccessor, Type modelType, string propertyName )
    {
        var metadata = base.CreateMetadata( attributes, containerType, modelAccessor, modelType, propertyName );

        var additionalHtmlValues = attributes.OfType<AdditionalHtml>().FirstOrDefault();

        if ( additionalHtmlValues != null )
        {
            metadata.AdditionalValues.Add( "AdditionalHtml", additionalHtmlValues );
        }

        return metadata;
    }
}

Add helper:

添加帮手:

public static class HtmlAttributesHelper
{
    public static string GetHtmlAttribute<T> ( this T model, Expression<Func<T, object>> expression, string attribName )
    {
        string strDefault = String.Empty;
        MemberInfo member = null;

        switch ( expression.Body.NodeType )
        {
            case ExpressionType.Lambda:
            case ExpressionType.Convert:
                {
                    var body = expression.Body as UnaryExpression;
                    if ( body == null )
                        return strDefault;
                    var operand = body.Operand as MemberExpression;
                    if ( operand == null )
                        return strDefault;
                    member = operand.Member;
                    break;
                }
            case ExpressionType.MemberAccess:
                {
                    var body = expression.Body as MemberExpression;
                    if ( body == null )
                        return strDefault;
                    member = body.Member;
                    break;
                }
            default:
                {
                    return expression.Body.ToString() + " " + expression.Body.NodeType.ToString();
                }
        }

        if ( member == null )
            return strDefault;

        var attr = member.GetCustomAttributes( typeof( AdditionalHtml ), false );
        if ( attr.Length > 0 )
        {
            return ( attr [ 0 ] as AdditionalHtml ).OptionalAttributes() [ attribName.ToLower() ].ToString();
        }

        // Return Name of Property if AdditionalHtml.Id is empty
        return attribName == "Id" ? member.Name : strDefault;
    }

    public static string GetHtmlId<T> ( this T model, Expression<Func<T, object>> expression )
    {
        return model.GetHtmlAttribute( expression, "Id" );
    }
}

Register provider in Global.asax:

在 Global.asax 中注册提供者:

protected void Application_Start ()
    {
        AreaRegistration.RegisterAllAreas();

        //....
        ModelMetadataProviders.Current = new MetadataProvider();
    }

In your model u can use AdditionHtml like as:

在您的模型中,您可以像这样使用 AdditionHtml:

[AdditionalHtml( Id = "OrderNo", CssClass = ShortTextStyle, Disabled = true )]
    public string OrderNo { get; set; }

And now you can use sintax for js (in view):

现在你可以对 js 使用 sintax(在视图中):

$('#@Model.GetHtmlId( x => x.PropertyName)')

And in view, you can use:

在视图中,您可以使用:

@Html.DisplayFor( x => x.FormDate )

Html attributes attached automatically

自动附加 HTML 属性

回答by Harbinger

Just add a HiddenFor above the column. This will give you a ID to use for what you need. Simple and does the trick for you to grab that value by ID.

只需在列上方添加一个 HiddenFor。这将为您提供一个 ID 以用于您需要的内容。简单并且可以让您通过 ID 获取该值。

<%= Html.HiddenFor(model => model.DeviceComponentName)%>
<%= Html.DisplayFor(model => model.DeviceComponentName)%>

回答by CrazyWebDeveloper

HtmlHelpers have overrides that allow you to pass in an object, or a dictionary, to add attributes to the generated html tag:

HtmlHelpers 具有覆盖,允许您传入一个对象或字典,以向生成的 html 标记添加属性:

@Html.DisplayFor(model => model.DeviceComponentName, new { id = "myId" })

@Html.DisplayFor(model => model.DeviceComponentName, new Dictionary<string, object>() { { "id", "myId" } })

or

或者

@Html.DisplayFor(model => model.DeviceComponentName, new { id = ViewData.TemplateInfo.GetFullHtmlFieldName("DeviceComponentName") })

@Html.DisplayFor(model => model.DeviceComponentName, new Dictionary<string, object>() { { "id", ViewData.TemplateInfo.GetFullHtmlFieldName("DeviceComponentName" } })

UPDATE:

更新:

After reviewing the updated code, and re-reading the question, here is what I would suggest - which is similar to your first idea.

在查看更新的代码并重新阅读问题后,这是我的建议 - 这与您的第一个想法相似。

<td class="editableValue" id="<%= ViewData.TemplateInfo.GetFullHtmlFieldName("DeviceComponentName") %>">
  <%= Html.DisplayFor(model => model.DeviceComponentName)%>
  <button type="button" id="ComponentTreeButton" class="nestedDialogButton">...</button>
</td>

You shouldn't need to add an extra div inside the TD, because you can modify the value within the td directly via the jQuery. I believe the following should accomplish this:

您不需要在 TD 内添加额外的 div,因为您可以直接通过 jQuery 修改 td 内的值。我相信以下应该可以做到这一点:

$('#DeviceComponentName').html('newValue');

回答by vijay as vj

We Can't Create id for Displayfor() control in razor .. We can use html control like label of span instead of Displayfor() control . Other Wise we can put displayfor control in span control . now we can create id for span . this the way we have to do ..

我们无法在 razor 中为 Displayfor() 控件创建 id .. 我们可以使用 html 控件,如 span 标签而不是 Displayfor() 控件。其他明智的我们可以将 displayfor control 放在 span control 中。现在我们可以为 span 创建 id 。这是我们必须做的方式..

example <span id="spanid">@Html.Displayfor(modelItem => item.id) </span>

例子 <span id="spanid">@Html.Displayfor(modelItem => item.id) </span>

回答by LawMan

Here's naspinski solution with the ability to add htmlAttributes.

这是能够添加 htmlAttributes 的 naspinski 解决方案。

    public static MvcHtmlString DisplayWithIdFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object htmlAttributes, string wrapperTag = "div")
    {
        var id = helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression));

        if (htmlAttributes != null)
        {
            var tag = new TagBuilder(wrapperTag);
            tag.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes) as IDictionary<string, object>);
            tag.Attributes.Add("id", id);
            tag.SetInnerText(helper.DisplayFor(expression).ToHtmlString());

            return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
        }
        else
        {
            return MvcHtmlString.Create(string.Format("<{0} id=\"{1}\">{2}</{0}>", wrapperTag, id, helper.DisplayFor(expression)));
        }
    }

回答by Blue Clouds

The easiest solution for me was to use a readonly text box. @Html.TextBoxFor(u => u.Visibilidade, new { disabled = "disabled" })

对我来说最简单的解决方案是使用只读文本框。@Html.TextBoxFor(u => u.Visibilidade, new { disabled = "disabled" })