我正在构建一个需要拥有2个不同版本的Play 2.1.0(Java)应用程序:桌面Web应用程序和移动Web应用程序。我正在寻找一种不会修改控制器的方法。逻辑,但依赖于路由。理想的行为应该是:
我是否可以通过路由行为进行连接,例如,将.mob附加到视图名称,以便呈现视图为main.scala.html
用于桌面,main.scala.mob.html
用于移动设备?这将是理想的,因为控制器不需要更改(或丑陋的ifs),并且每个视图都需要拥有它自己的移动版本。我想我此时需要请求来执行设备检测。如果没有针对特定操作实施移动视图,它甚至可以回退到桌面视图。
有什么想法吗?
谢谢, 贡萨洛
答案 0 :(得分:1)
我最终编写了需要移动版本和其他操作的操作。为了实现这一点,我创建了一个@Mobile
运行时注释,我用它来注释这些动作和移动视图的名称。所有带注释的操作都将由以下MobileAction
组成,它执行设备检测:
public class MobileAction extends Action<Mobile> {
public MobileAction() {
}
public MobileAction(Mobile configuration, Action<?> delegate) {
this.configuration = configuration;
this.delegate = delegate;
}
@Override
public Result call(Http.Context ctx) throws Throwable {
final Http.Request request = ctx.request();
final String userAgent = request.getHeader("User-Agent");
// See https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
if (userAgent.contains("Mobi")) {
ctx.args.put("viewName", configuration.value());
}
return delegate.call(ctx);
}
}
我实现了一个DynamicRendered
类,它查找viewName
参数(可选择由@Mobile
注入)并使用反射来呈现相应的视图。
public class DynamicRenderer {
public static Html render(String viewName, Object... args) {
final Map<String, Object> ctxArgs = Http.Context.current().args;
final String view = ctxArgs.containsKey("viewName") ? ((String) ctxArgs.get("viewName")) : viewName;
// Get argument classes
final Class[] argClasses = new Class[args.length];
for (int i=0; i<args.length; i++) {
argClasses[i] = args[i].getClass();
}
try {
// Get view render method and invoke
final Class<?> clazz = Class.forName(view);
final Method render = clazz.getDeclaredMethod("render", argClasses);
final Html html = ((Html) render.invoke(null, args));
return html;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
然后,我打电话给ok(viewName.render(...))
ok(DynamicRenderer.render("viewName", ...))
答案 1 :(得分:0)
听起来你需要的是使用CSS + JS样式库,如Foundation 5或Bootstrap。通过在生成的html中使用css标记,可以允许您指定视图在不同屏幕大小中的显示方式。 Lookup Foundation文档,他们解释了如何做到这一点。