2012-03-13 23 views
36

He estado usando editor de plantillas en el pasado de esta manera, mediante la aplicación de la siguiente anotación de datos:ASP.NET MVC redactor plantillas/UIHint con parámetros

[UIHint("SomeTemplate")] 

modelo de vista:

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

Si quería utilizar un control de selector de fecha específico en lugar de uno regular, puede implementarse de la siguiente manera.

Ejemplo:

Para mis campos de ID, me gustaría hacer uso del componente de auto-completar jQuery.

Pregunta:

¿Cómo hago para pasar parámetros adicionales a la vista UIHint parcial para LabSampleTypeID y LabSampleDetailID? (Como Id gustaría tener un redactor de plantilla de autocompletar que va a tomar la URL y los nombres de propiedad, por ejemplo)

lo que creo que mi auto-completar Editor-Plantilla/Parcial debe verse como:

$(".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] 
        } 
       })); 
      } 
     }) 
    } 
}); 
+2

FYI, no es necesario el UIHint para el DateTime. Ya es * un * DateTime, por lo que ya usará una plantilla DateTime.cshtml si existe. Lo necesita para los otros que no son del mismo tipo que el nombre de la plantilla. –

Respuesta

68

se puede utilizar el atributo AdditionalMetadata:

[UIHint("DateTime")] 
[AdditionalMetadata("foo", "bar")] 
public DateTime Date { get; set; } 

y en la plantilla:

@ViewData.ModelMetadata.AdditionalValues["foo"] 

lo que si quería pasar una url:

[UIHint("DateTime")] 
[AdditionalMetadata("controller", "somecontroller")] 
[AdditionalMetadata("action", "someaction")] 
[AdditionalMetadata("property", "someproperty")] 
public DateTime Date { get; set; } 

y en su plantilla:

@{ 
    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> 
+4

La clase 'UHint' tiene un constructor con' params object [] controlParameters' adicionales. ¿Cuál es el propósito de esto? –

+0

'UHint' controlParameters parece ser más sutable para este – Sel

3

Se podría utilizar el UHint sin AdditionalMetadata atributo, pero algo de código adicional es requred

[UIHint("DateTime", null, "key1", "value1", "key2", "value2")] 
public DateTime Date { get; set; } 

anular CrearMetadatos:

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

Registro CustomMetadataProvider:

public static void Application_Start() 
    { 
     ModelMetadataProviders.Current = new CustomMetadataProvider(); 
    } 

y en su plantilla:

@{ 
     IDictionary<string, object> values = (IDictionary<string, object>) 
ViewData.ModelMetadata.AdditionalValues[CustomMetadataProvider.UiHintControlParameters]; 
    } 
+0

Hola, probé tu código, pero al intentar registrar el proveedor personalizado dice que no puede convertir el tipo de destino a System.Web.Mvc.ModelMetadataProvider, ¿alguna idea? –

+0

La anulación que creamos se extiende desde 'DataAnnotationsModelMetadataProvider' como su ejemplo, pero el 'ModelMetadataProviders.Current' espera un ModelMetadataProvider. –

+0

** Ciaran **, asegúrate de anular 'DataAnnotationsModelMetadataProvider' del espacio de nombres' System.Web.Mvc', no 'System.Web.Http.Metadata.Providers' – Sel