ASP.NET MVC Editor-Templates/UIHint с параметрами
В прошлом я использовал Редактор-Шаблоны, применяя следующие аннотации данных:
[UIHint("SomeTemplate")]
ViewModel:
public class MicroViewModel
{
public IEnumerable<LabMicro> Micros { get; set; }
[UIHint("DateTime")]
public DateTime Date { get; set; }
public int CaseNo { get; set; }
[UIHint("SampleTypes")]
public int LabSampleTypeID { get; set; }
[UIHint("SampleDetails")]
public int LabSampleDetailID { get; set; }
}
Если бы я хотел использовать определенный элемент управления выбора даты, а не обычный, его можно реализовать следующим образом.
Пример:
@model DateTime?
@Html.TextBox("", String.Format("{0:yyyy-MM-dd}", Model.HasValue ?
Model : DateTime.Today), new { @class = "dp", style="width:100px" })
<script type="text/javascript">
$(document).ready(function () {
$(".dp").datepicker({
changeMonth: true,
changeYear: true,
dateFormat: 'yy-mm-dd'
});
});
</script>
Для моих идентификационных полей я хотел бы использовать компонент автозаполнения jQuery.
Вопрос:
Как мне перейти к передаче дополнительных параметров в частичное представление UIHint
для LabSampleTypeID
и LabSampleDetailID
? (Так как идентификатор должен иметь автозаполненный редактор-шаблон, который, например, будет содержать URL-адрес и имена свойств)
Я думаю, что мой автозаполненный редактор-шаблон/Partial должен выглядеть так:
$(".auto").autocomplete({
source: function(request, response) {
$.ajax({
url: '[#URL_TO_USE]',
dataType: "json",
data: {
filter: request.term
},
success: function(data) {
response($.map(eval(data), function(item) {
return {
label: item.[#PROPERTY_TO_USE]
}
}));
}
})
}
});
Ответы
Ответ 1
Вы можете использовать атрибут AdditionalMetadata
:
[UIHint("DateTime")]
[AdditionalMetadata("foo", "bar")]
public DateTime Date { get; set; }
и в шаблоне:
@ViewData.ModelMetadata.AdditionalValues["foo"]
поэтому если вы хотите передать URL-адрес:
[UIHint("DateTime")]
[AdditionalMetadata("controller", "somecontroller")]
[AdditionalMetadata("action", "someaction")]
[AdditionalMetadata("property", "someproperty")]
public DateTime Date { get; set; }
и в вашем шаблоне:
@{
var values = ViewData.ModelMetadata.AdditionalValues;
}
<script type="text/javascript">
$('.auto').autocomplete({
source: function (request, response) {
$.ajax({
url: '@Url.Action((string)values["action"], (string)values["controller"])',
dataType: "json",
data: {
filter: request.term
},
success: function (data) {
response(
$.map(eval(data), function (item) {
return {
label: item['@values["property"]']
}
})
);
}
});
}
});
</script>
Ответ 2
Вы можете использовать UHint без атрибута AdditionalMetadata, но требуется дополнительный код
[UIHint("DateTime", null, "key1", "value1", "key2", "value2")]
public DateTime Date { get; set; }
переопределить CreateMetadata:
public class CustomMetadataProvider : DataAnnotationsModelMetadataProvider
{
public const string UiHintControlParameters = "UiHintControlParameters";
protected override ModelMetadata CreateMetadata(
IEnumerable<Attribute> attributes,
Type containerType,
Func<object> modelAccessor,
Type modelType,
string propertyName)
{
ModelMetadata metadata = base.CreateMetadata(
attributes,
containerType,
modelAccessor,
modelType,
propertyName);
IEnumerable<UIHintAttribute> uiHintAttributes = attributes.OfType<UIHintAttribute>();
UIHintAttribute uiHintAttribute = uiHintAttributes.FirstOrDefault(a => string.Equals(a.PresentationLayer, "MVC", StringComparison.OrdinalIgnoreCase))
?? uiHintAttributes.FirstOrDefault(a => String.IsNullOrEmpty(a.PresentationLayer));
if (uiHintAttribute != null)
{
metadata.AdditionalValues.Add(UiHintControlParameters, uiHintAttribute.ControlParameters);
}
return metadata;
}
Зарегистрировать CustomMetadataProvider:
public static void Application_Start()
{
ModelMetadataProviders.Current = new CustomMetadataProvider();
}
и в вашем шаблоне:
@{
IDictionary<string, object> values = (IDictionary<string, object>)
ViewData.ModelMetadata.AdditionalValues[CustomMetadataProvider.UiHintControlParameters];
}