2012-10-18 2 views
9

Tôi muốn có thể hiển thị một số văn bản, nhưng cũng có văn bản có thể sửa đổi được thông qua jQuery.MVC3 Html.DisplayFor - Có thể có điều khiển này tạo ID không?

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

Nếu tôi sử dụng EditorFor thay cho DisplayFor, tôi sẽ thấy ID cho điều khiển nhập. Tuy nhiên, tôi không muốn giá trị có thể chỉnh sửa theo cách đó. Vì vậy, tôi đã làm cho nó một DisplayFor, nhưng nó không tạo ra một tài sản ID cho phần tử.

Nên tôi chỉ quấn DisplayFor trong một div và làm điều gì đó như:

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

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

Hoặc là có một cách sạch hơn để đạt được điều này?

Cập nhật: Có cách nào không phụ thuộc vào chuỗi được mã hóa cứng không? Một cái gì đó mà liên kết với các đối tượng chính nó vì vậy nếu tên tài sản của tôi thay đổi tôi muốn có được một lỗi biên dịch?

Ngoài ra, tôi đang sử dụng mã này, nhưng tôi không thấy một giá trị ID xuất hiện:

<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> 

Trả lời

18

Để tránh các đầu vào 'chuỗi ma thuật' (trong trường hợp thuộc tính mô hình của bạn thay đổi), bạn có thể thực hiện việc này bằng tiện ích mở rộng. Nó cũng làm cho mã sạch hơn nhiều:

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))); 
} 

Sau đó chỉ cần sử dụng nó như thế này:

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

Sẽ tạo ra

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

Hoặc nếu bạn muốn nó được bao bọc trong một khoảng:

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

Điều gì sẽ làm:

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

Non-Razor

Đối với cú pháp Razor thuốc, bạn chỉ cần sử dụng nó như thế này:

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

và:

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

Đã thêm cú pháp không phải là dao cạo - mã tự giữ nguyên. – naspinski

+2

Cú pháp không phải dao cạo có phải là @ trước Html không? –

+1

bạn đúng Sean: P đã chỉnh sửa – naspinski

5

bạn phải sử dụng:

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

Đối với id năng động và các tài sản khác, tôi sử dụng :

class cho siêu dữ liệu:

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 cho nhà cung cấp siêu dữ liệu:

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"); 
    } 
} 

cung cấp dịch vụ đăng ký trong toàn cầu.tuyến Asax:

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

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

Trong mô hình của bạn u có thể sử dụng AdditionHtml như là:

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

Và bây giờ bạn có thể sử dụng sintax cho js (theo quan điểm):

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

Và theo quan điểm, bạn có thể sử dụng:

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

Thuộc tính Html tại tached tự động

+1

Có cách nào để năng động không? Nếu tên tài sản của tôi thay đổi thì sao? –

+2

@SeanAnderson yes bạn có thể sử dụng ViewBag hoặc ViewData để chuyển giá trị id từ bộ điều khiển '@ Html.DisplayFor (model => model.DeviceComponentName, new {id = ViewBag.DeviceComponentID})' –

2

HtmlHelpers có ghi đè cho phép bạn vượt qua trong một đối tượng, hoặc một cuốn từ điển, thêm thuộc tính vào thẻ html tạo:

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

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

hoặc

@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:

Sau khi xem xét mã được cập nhật và đọc lại câu hỏi, dưới đây là những gì tôi sẽ đề xuất - tương tự như ý tưởng đầu tiên của bạn.

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

Bạn không cần phải thêm thêm div bên trong TD, vì bạn có thể sửa đổi giá trị trong td trực tiếp thông qua jQuery. Tôi tin rằng những điều sau đây nên thực hiện điều này:

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

Tôi không sử dụng cú pháp Razor, nhưng tôi không thấy ID hiển thị khi tôi sử dụng một trong hai ví dụ. Tôi sẽ chỉnh sửa bài đăng hàng đầu những gì tôi đã thử. –

3

Chỉ cần thêm một HiddenFor trên cột. Điều này sẽ cung cấp cho bạn một ID để sử dụng cho những gì bạn cần. Đơn giản và thực hiện mẹo để bạn lấy giá trị đó bằng ID.

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

Chúng tôi không thể tạo id cho Displayfor() điều khiển trong dao cạo .. Chúng tôi có thể sử dụng điều khiển html như nhãn span thay vì Displayfor() kiểm soát. Khác khôn ngoan, chúng tôi có thể đặt displayfor kiểm soát trong kiểm soát nhịp. bây giờ chúng ta có thể tạo id cho span. này cách chúng ta phải làm ..

dụ <sapn id="spanid">@Html.Displayfor(modelItem => item.id) </sapn>

0

Đây là giải pháp naspinski với khả năng thêm htmlAttributes.

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))); 
     } 
    } 
0

Giải pháp dễ nhất cho tôi là sử dụng hộp văn bản chỉ đọc. @ Html.TextBoxFor (u => u.Visibilidade, mới {disabled = "disabled"})