ASP.NET MVC 1 프로젝트에서 HTML5 데이터 속성 을 사용하려고합니다 . (저는 C # 및 ASP.NET MVC 초보자입니다.)
<%= Html.ActionLink("« Previous", "Search",
new { keyword = Model.Keyword, page = Model.currPage - 1},
new { @class = "prev", data-details = "Some Details" })%>
위의 htmlAttributes에서 “data-details”는 다음과 같은 오류를 발생시킵니다.
CS0746: Invalid anonymous type member declarator. Anonymous type members
must be declared with a member assignment, simple name or member access.
data_details를 사용할 때 작동하지만 사양에 따라 “data-“로 시작해야한다고 생각합니다.
내 질문 :
- 이 작업을 수행하고 Html.ActionLink 또는 유사한 Html 헬퍼와 함께 HTML5 데이터 속성을 사용하는 방법이 있습니까?
- 사용자 정의 데이터를 요소에 첨부하는 다른 대체 메커니즘이 있습니까? 이 데이터는 나중에 JS에 의해 처리됩니다.
답변
업데이트 : 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를 사용하는 경우 MVC3의 소스 코드에서 빌린이 정적 메서드를 만들어 MVC 3이 수행하는 작업을 모방 할 수 있습니다.
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" })) %>
올바른 data- * 속성을 렌더링합니다.
<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" })%>
나는 JohnnyO가 이미 이것을 언급 한 것을 본다.
답변
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 헬퍼 확장 기능으로 구현하면 기존 ActionLink와 유사하게 사용됩니다.
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" }) %>
단순 🙂
편집하다
여기에 조금 더 쓰기
답변
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));
}
}