2014-06-23 4 views
2

저는 데스크톱 웹 앱과 모바일 웹 앱의 두 가지 버전이 필요한 Play 2.1.0 (Java) 앱을 제작하고 있습니다. 내가 컨트롤러의 논리를 수정하지 않는 방법을 찾고 있지만 라우팅에 의존합니다. 이상적인 동작해야한다 :Play Framework 2 - 기기마다 다른보기

  • 경로는
  • 보기 바탕 화면에 같은 모바일 있습니다
  • 컨트롤러 데스크톱에 대한 동일 및 모바일있는 모바일 및 데스크톱을위한 다르지만, 명명 규칙을 공유 할 수 있습니다.

내가 렌더링보기 바탕 화면에 대한 main.scala.html 및 모바일 main.scala.mob.html 그래서 라우팅 동작으로 연결 및 말하자면, 뷰 이름에 .mob를 추가 할 수 있습니다 곳이 있습니까? 제어기가 변경 (또는 추한 if)을 필요로하지 않고 각보기가 자신의 모바일 버전을 가질 필요가 있기 때문에 이것은 이상적입니다. 장치 감지를 수행하려면이 시점에서 요청이 필요합니다. 특정 작업에 대해 모바일보기가 구현되지 않은 경우 바탕 화면보기로 폴백 할 수 있다면 더 차갑습니다.

아이디어가 있으십니까?

감사합니다, 곤잘로

답변

0

다른 작업으로 모바일 버전이 필요한 작업을 작성하게되었습니다. 이를 달성하기 위해 모바일보기의 이름을 사용하여 주석을 달기 위해 사용한 런타임 주석을 @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); 
    } 
} 

는 난 (임의로 @Mobile 의해 분사)를 viewName 인자를 검색하고 해당 뷰를 렌더링하기 위해 반사를 이용하는 DynamicRendered 클래스를 구현 하였다.

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", ...))

0

은 재단 5, 부트 스트랩으로 CSS + JS 스타일 라이브러리를 사용하는 것입니다 당신이 필요한 것 같네요. 그것들은 생성 된 HTML에서 CSS 태그를 사용하여보기가 다른 화면 크기로 표시되는 방법을 지정할 수있게합니다. Lookup Foundation 문서, 어떻게하는지 설명합니다.

+0

감사를 부르지 만보기는 완전히 다른 것입니다. 따라서 CSS + JS 솔루션으로는 충분하지 않습니다. – monsieurBelbo

+0

당신에게 달려 있습니다 ... FYI Foundation은 스크린 크기를 기반으로 UI의 특정 부분을 동적으로 숨기거나 표시 할 수있는 기능을 가지고 있습니다. 모든 것을 HTML로 렌더링 한 다음 필요한 것만 표시하려는 경우. 여분의 시간이 5 분이면 여기를보십시오. http://foundation.zurb.com/docs/components/visibility.html –

+0

나는 이것을 투표했습니다. 오늘 데스크톱, 태블릿 및 모바일 화면에서 내보기가 괜찮아 보이게하는 동일한 작업을했습니다. 나는 부트 스트랩 3.3.6과 그것의 반응 유틸리티의 도움으로이 문제를 해결했다. 이 답변이 왜 누군가에 의해 다운 되었는 지 모르지만 실제로 Boostrap이 반응 형 툴링을 발전 시켰을 때 2014 년에는 조언이 좋았고 2014 년에는 더 나아졌습니다. –