Como resultado de esta respuesta: https://stackoverflow.com/a/10708026/694597, me pregunto cómo devolver una vista inherente a un controlador específico cuando se usa un controlador genérico.Al usar un controlador genérico, ¿cómo devolver una vista inherente a un controlador específico?
Respuesta
Cuando se procesa una vista en una acción del controlador, que acaba de invocar una función sencilla que ha sido generado por el motor de plantillas:
public Application extends Controller {
public static Result index() {
return ok(views.html.index.render(42));
}
}
Aquí, render
es un método del objeto index
la que tiene el tipo Template1<Integer, Html>
.
Ahora la pregunta es: ¿cómo escribir un controlador genérico capaz de invocar una vista específica para otro controlador? O simplemente: cómo abstraer con vistas?
veo dos soluciones: inversion of control y reflexión.
Veamos cómo implementar ambos en un caso de uso simple. Digamos que tiene la siguiente genérica clase Shower<T>
capaz de calcular una respuesta HTTP que contiene una representación HTML de cualquier valor de tipo T
:
public class Shower<T> {
public Result show(T value) {
// TODO return an HTML representation of `value`
}
}
Inversión de Control
Para implementar Shower<T>
mediante la inversión de control sólo tenemos que inyectar el valor Template1<T, Html>
utilizada para realizar la prestación:
public class Shower<T> {
public final Template1<T, Html> template;
public Shower(Template1<T, Html> template) {
this.template = template;
}
public Result show(T value) {
return ok(template.render(value));
}
}
utilizarlo en un controlador, crear una instancia estática de Shower<T>
e inyectarlo la plantilla a utilizar:
public class Application extends Controller {
public static Shower<Foo> foo = new Shower<Foo>(views.html.Foo.show.ref());
}
Reflexión
puede que le resulte demasiado repetitivo a tener que inyectar de forma explícita la plantilla a utilizar para cada instancia de Shower<T>
, por lo que puede tener la tentación de recuperarlo por reflexión, basado en una convención de nomenclatura, por ejemplo para mostrar un valor de tipo Foo
, sólo tiene que buscar un objeto denominado show
en el paquete views.html.Foo
:
public class Shower<T> {
private final Class<T> clazz;
public Shower(Class<T> clazz) {
this.clazz = clazz;
}
public Result show(T value) throws Exception {
Class<?> object = Play.application().classLoader().loadClass("views.html." + clazz.getSimpleName() + ".show$");
Template1<T, Html> template = (Template1<T, Html>)object.getField("MODULE$").get(null);
return ok(template.render(value));
}
}
(esa es la manera de acceder a Scala objetos utilizando la reflexión)
Se puede utilizar de la siguiente manera en una controlador:
public class Application extends Controller {
public static Shower<Foo> foo = new Shower<Foo>(Foo.class);
}
Pros y contras
La solución basada en la reflexión requiere menos texto estándar en el sitio de llamadas, pero el hecho de que se basa en una convención de nomenclatura lo hace más frágil. Además, esta solución solo fallará en el tiempo de ejecución cuando fallará, mientras que la primera solución mostrará las plantillas que faltan en el momento de la compilación.Por último, pero no menos importante, la solución basada en la reflexión puede agregar un poco de sobrecarga de rendimiento debido a la reflexión.
- 1. ¿Cómo agrego una ruta MVC a un controlador específico?
- 2. ¿Cómo usar un UISplitViewController como un controlador de vista modal?
- 3. Presentar un controlador de vista específico desde AppDelegate
- 4. Llamar a un controlador de vista padre (a través de un controlador de navegación)
- 5. ¿Cómo se accede al controlador de vista de un súper?
- 6. asp.net controlador genérico mvc
- 7. ¿cómo puedo acceder a la vista de un controlador de vista padre desde un controlador de vista hijo?
- 8. ¿Sesión en controlador genérico?
- 9. ¿Puede un controlador de vista presentado también ser un controlador de vista de presentación?
- 10. ¿Cómo puedo devolver el HTML del controlador MVC a un div en mi vista?
- 11. Redirigir un controlador a otro Controlador
- 12. ¿Cómo destaco el controlador de vista debajo de un controlador de vista presionado?
- 13. múltiples UIActionSheets en un controlador de vista
- 14. UITabBarController: cómo acceder a un controlador de vista?
- 15. ¿Cómo puedo declarar explícitamente una vista desde un controlador Rails?
- 16. ¿Cómo puedo usar el reflejo para devolver todas las clases subclases desde un genérico, sin dar un tipo genérico específico?
- 17. ExtJS 4 cómo crear y visualizar un nuevo controlador/vista desde otro controlador/vista?
- 18. En Meteor, ¿cómo puedo crear un controlador de eventos genérico?
- 19. Xcode: Cómo crear un controlador de vista emergente que aparece en otro controlador de vista
- 20. ¿Hay alguna forma de devolver un resultado de acción desde el controlador B desde el controlador A y proporcionar un modelo específico a B?
- 21. Rendering Parciales En Ver un controlador de Vista a otro controlador de rieles en
- 22. Llegar al controlador de vista que empujó el controlador de vista visible
- 23. ¿Cómo devolver HTML directamente desde un controlador Rails?
- 24. vista de rieles sin un controlador
- 25. ¿Cómo puedo "conectar" una vista de tabla a un controlador de vista
- 26. Devolver una vista desde un área diferente
- 27. ¿Cómo usar el asistente de vista parcial de Zend Framework fuera de un controlador o vista?
- 28. ASP.NET MVC: ¿Puede una vista parcial tener un controlador?
- 29. presentes vista modal controlador
- 30. ¿Cómo eliminar un controlador de vista específico de la pila uinavigationcontroller?
'ref()'! oh, este conocimiento va a ser extremadamente útil! Muchas gracias por explicar esto! – Daniel
¡Me gusta su solución de inversión de control! Pero si tienes varios métodos en tu 'Ducha 'también debes pasar múltiples vistas. ¿Sería útil usar también el [Patrón del constructor] (http://en.wikipedia.org/wiki/Builder_pattern) para ese problema? (ver también: Bloch, J. _Eficaz Java_ -> Elemento 2) –
Hasta donde yo entiendo, este patrón le permite escribir un código más legible en el sitio de llamadas, pero aún así requiere que pase todas las vistas. –