Как использовать тире в HTML - 5 data-* атрибуты в ASP.NET MVC



Я пытаюсь использовать HTML5 data-attributes в моем ASP.NET проект MVC 1. (Я-C# и ASP.NET MVC новичок.)



 <%= Html.ActionLink("« Previous", "Search",
new { keyword = Model.Keyword, page = Model.currPage - 1},
new { @class = "prev", data-details = "Some Details" })%>


"данные-детали" в приведенных выше htmlAttributes дают следующую ошибку:



 CS0746: Invalid anonymous type member declarator. Anonymous type members 
must be declared with a member assignment, simple name or member access.


он работает, когда я использую data_details, но я думаю, что он должен начинаться с "data-" в соответствии со спецификацией.



мои вопросы:




  • есть ли способ заставить это работать и использовать атрибуты данных HTML5 с помощью Формат html.ActionLink или аналогичные HTML-помощники ?

  • есть ли другой альтернативный механизм для присоединения пользовательских данных к элементу? Эти данные должны быть обработаны позже JS.

620   8  

8 ответов:

обновление: MVC 3 и более новые версии имеет встроенную поддержку для этого. См. высоко оцененный ответ JohnnyO ниже для рекомендуемых решений.

Я не думаю, что есть какие-либо непосредственные помощники для достижения этого, но у меня есть две идеи для вас попробовать:

// 1: pass dictionary instead of anonymous object
<%= Html.ActionLink( "back", "Search",
    new { keyword = Model.Keyword, page = Model.currPage - 1},
    new Dictionary<string,Object> { {"class","prev"}, {"data-details","yada"} } )%>

// 2: pass custom type decorated with descriptor attributes
public class CustomArgs
{
    public CustomArgs( string className, string dataDetails ) { ... }

    [DisplayName("class")]
    public string Class { get; set; }
    [DisplayName("data-details")]
    public string DataDetails { get; set; }
}

<%= Html.ActionLink( "back", "Search",
    new { keyword = Model.Keyword, page = Model.currPage - 1},
    new CustomArgs( "prev", "yada" ) )%>

просто идеи, не проверял его.

эта проблема была решена в ASP.Net MVC 3. Теперь они автоматически преобразуют подчеркивания в свойствах атрибутов html в тире. Им повезло на этом, так как подчеркивания не являются законными в атрибутах html, поэтому MVC может уверенно подразумевать, что вы хотите тире при использовании подчеркивания.

например:

@Html.TextBoxFor(vm => vm.City, new { data_bind = "foo" })

отобразит это в MVC 3:

<input data-bind="foo" id="City" name="City" type="text" value="" />

если вы все еще используете старую версию MVC, вы можете имитировать то, что делает MVC 3 создание этого статического метода, который я позаимствовал из исходного кода MVC3:

public class Foo {
    public static RouteValueDictionary AnonymousObjectToHtmlAttributes(object htmlAttributes) {
        RouteValueDictionary result = new RouteValueDictionary();
        if (htmlAttributes != null) {
            foreach (System.ComponentModel.PropertyDescriptor property in System.ComponentModel.TypeDescriptor.GetProperties(htmlAttributes)) {
                result.Add(property.Name.Replace('_', '-'), property.GetValue(htmlAttributes));
            }
        }
        return result;
    }
}

и тогда вы можете использовать его следующим образом:

<%: Html.TextBoxFor(vm => vm.City, Foo.AnonymousObjectToHtmlAttributes(new { data_bind = "foo" })) %>

и это будет отображать правильные данные - * атрибут:

<input data-bind="foo" id="City" name="City" type="text" value="" />

Это даже проще, чем все, что предлагалось выше. Атрибуты данных в MVC, которые включают тире ( - ), обслуживаются с использованием подчеркивания (_).

<%= Html.ActionLink("« Previous", "Search",
 new { keyword = Model.Keyword, page = Model.currPage - 1},
 new { @class = "prev", data_details = "Some Details"   })%>

Я вижу, Джонни уже упоминал об этом.

в mvc 4 может быть отображен с подчеркиванием ("_")

бритвы:

@Html.ActionLink("Vote", "#", new { id = item.FileId, }, new { @class = "votes", data_fid = item.FileId, data_jid = item.JudgeID, })

Рендеринг Html

<a class="votes" data-fid="18587" data-jid="9" href="/Home/%23/18587">Vote</a>

вы можете реализовать это с помощью новой вспомогательной функции расширения Html, которая затем будет использоваться аналогично существующим ActionLinks.

public static MvcHtmlString ActionLinkHtml5Data(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName, object routeValues, object htmlAttributes, object htmlDataAttributes)
{
    if (string.IsNullOrEmpty(linkText))
    {
        throw new ArgumentException(string.Empty, "linkText");
    }

    var html = new RouteValueDictionary(htmlAttributes);
    var data = new RouteValueDictionary(htmlDataAttributes);

    foreach (var attributes in data)
    {
        html.Add(string.Format("data-{0}", attributes.Key), attributes.Value);
    }

    return MvcHtmlString.Create(HtmlHelper.GenerateLink(htmlHelper.ViewContext.RequestContext, htmlHelper.RouteCollection, linkText, null, actionName, controllerName, new RouteValueDictionary(routeValues), html));
}

и вы называете это так ...

<%: Html.ActionLinkHtml5Data("link display", "Action", "Controller", new { id = Model.Id }, new { @class="link" }, new { extra = "some extra info" })  %>

Simples : -)

edit

чуть больше писать здесь

Я закончил тем, что использовал обычную гиперссылку вместе с Url.Action, например:

<a href='<%= Url.Action("Show", new { controller = "Browse", id = node.Id }) %>'
  data-nodeId='<%= node.Id %>'>
  <%: node.Name %>
</a>

Это уродливее, но у вас есть немного больше контроля над a тег, который иногда полезно в сильно AJAXified сайтах.

HTH

мне не нравится использовать чистый тег "a", слишком много ввода. Поэтому я пришел с решением. На вид это выглядит

<%: Html.ActionLink(node.Name, "Show", "Browse", 
                    Dic.Route("id", node.Id), Dic.New("data-nodeId", node.Id)) %>

реализация класса Dic

public static class Dic
{
    public static Dictionary<string, object> New(params object[] attrs)
    {
        var res = new Dictionary<string, object>();
        for (var i = 0; i < attrs.Length; i = i + 2)
            res.Add(attrs[i].ToString(), attrs[i + 1]);
        return res;
    }

    public static RouteValueDictionary Route(params object[] attrs)
    {
        return new RouteValueDictionary(Dic.New(attrs));
    }
}

Вы можете использовать его как это:

В Mvc:

@Html.TextBoxFor(x=>x.Id,new{@data_val_number="10"});

В Html:

<input type="text" name="Id" data_val_number="10"/>

Comments

    Ничего не найдено.