2016-08-18 4 views
2

우리는 JSF 2.2 + PrimeFaces 지원 응용 프로그램에서 SPA 방식을 사용하고 있습니다. 기본 개념은 원래 아주 잘 여기에 설명했다 : 콩을 @ViewScoped 사용할 때 우리가 아는 한이 SPA 방식을 사용하여,SPA JSF 2.2 응용 프로그램에서 @ViewScoped beans 제거

Refreshing dynamic content with AJAX in JSF using SPA approach

그러나 단점이있다.

실제로 동일한 JSF 뷰에 머무르기 때문에 새 SPA 내용으로 패널 그룹의 내용을 바꿀 때 @ViewScoped beans는 메모리에서 제거되지 않습니다.

나는 해결책을 찾았지만 정확한 접근 방법인지 그리고 누락 된 것이 있는지 알고 싶습니다. 새로운 SPA 후,

private void clearViewScopedBeans() { 
    Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap(); 
    for(Iterator<Map.Entry<String, Object>> it = viewMap.entrySet().iterator(); it.hasNext();) { 
     Map.Entry<String, Object> entry = it.next(); 
     it.remove();  
    } 
} 

이 사항을 확인해야합니다

기본적으로, SPA AJAX 요청시 렌더링 할 페이지의 이름을 보관 유지하는 우리의 NavigationService 콩,에, 우리는 항상 다음과 같은 코드를 실행 스 니펫이 렌더링되면 기존의 모든 @ViewScoped 빈이 제거됩니다.

그러나 위의 코드는 View Scoped beans 만 제거하지만 관련 View States는 제거하지 않는다고 생각합니다. 그 맞습니까 ?

나는 좀 더 논리 할 것으로 보인다 오래된 블로그 항목 발견 : http://javaevangelist.blogspot.sg/2014/08/jsf-21-tip-of-day-clearing-viewscope.html

을하지만 그것뿐만 아니라 올바른 있다면 난 몰라.

또한, 우리는 여러 창 탭을 지원하려는 경우, 현재의 SPA 조각 페이지 이름을 잡고 우리의 NavigationService 빈은,뿐만 아니라 @ViewScoped해야하며, 이것은 작은 문제가 소개합니다 다음을 실행하는 경우

을 기존의 모든 @ViewScoped 빈을 제거하기위한 위의 코드 ... NavigationService 빈을 제외해야합니다 !! 그렇지 않으면 새 페이지 대신 기본 SPA 페이지 이름으로 NavigationService의 새 인스턴스가 인스턴스화되므로 항상 동일한 페이지를로드해야합니다.

우리 코드는 결국 SPA 페이지 새로 고침에서 제거하지 않으려는 "제외 된"bean 이름의 맵 (즉, SPA를 포함하는 NavigationService bean 페이지 이름)

private void clearViewScopedBeans() { 
    Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap(); 
    for(Iterator<Map.Entry<String, Object>> it = viewMap.entrySet().iterator(); it.hasNext();) { 
     Map.Entry<String, Object> entry = it.next(); 
     if(!exclusionViewScopedBeans.contains(entry.getKey())) { 
      logger.info("Removing an instance of a @ViewScoped bean -> " + entry.getKey()); 
     it.remove(); 
     } 
    } 
} 

이제 질문 ... 이가 SPA 상황의이 종류를 처리하기위한 올바른 접근 방식인가? 여기에 뭔가가 빠졌습니까?

의견을 보내 주시면 대단히 감사하겠습니다 ... 미리 감사드립니다. 내가 많이 찾을 시도

private void clearViewScopedBeans() { 
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap(); 
for(Iterator<Map.Entry<String, Object>> it = viewMap.entrySet().iterator(); it.hasNext();) { 
    Map.Entry<String, Object> entry = it.next(); 
    it.remove();  
} 
} 

하지만 SPA는 "공식적인 권장"되지 않습니다 : 내가 생각

+1

그게 내가 사용하는 구현 - 정확한 접근 방식의 관점에서 얻을 수있는 인상은 JSF에서 이런 종류의 일을 피해야한다는 것이지만 때로는 당신이 필요합니다 – farrellmr

+0

대화 범위의 콩을 사용하지 않는 이유는 무엇입니까? – Kukeltje

+0

이 특정 프로젝트는 CDI 대신 Spring IoC를 사용하기 때문에 ... 지금까지 기본 제공 대화 범위가 없습니다. 필자는 지금까지 동일한 기능을 수행 할 수있는 새로운 (스프링) 스코프를 만들려고합니다. 지금까지 PrimeFaces TabView 구성 요소에 대한 TabScope를 성공적으로 만들었습니다. 각 탭에는 자체 JSF 빈 범위가있을 수 있습니다. 탭이 생성 될 때 만들어지며 탭이 닫힐 때 파괴됩니다. 같은 접근 방식을 사용하여 좀 더 일반적인 대화 범위를 개발할 수있을 것 같습니다 ... –

답변

0

는 당신 마이 켈보다/제거 SPA (단일 페이지 응용 프로그램)에 ViewScopedBeans을 지우기위한 더 나은 솔루션이 없습니다 JSF를 사용하는 방법은 다중 페이지 응용 프로그램이므로 SPA는 더 많은 주변 장치를 필요로합니다.

또는 Maikel, 다른 것을 찾았습니까? 아니면 다른 방법으로 사용합니까?

+0

SPA는 비회원도 아닙니다 ... 단지 기능을 사용할 수 없습니다 특정 뷰와 관련이 있습니다 ** 뷰잉 된 콩을 '악용하는'대신에 더 쉽게 제어 할 수있는 다른 범위의 콩을 사용할 수 있습니다 (그리고 대화를 생각할 수 있습니다). 그리고 이것을 읽을 수 있습니다. – Kukeltje

+0

안녕하세요 Radek와 Kukeltje. 지금까지는 서버 측과 관련하여 사용하고있는 접근 방식입니다. 결국 가장 큰 문제는 클라이언트 측에서였습니다. 많은 PrimeFaces jQuery UI 위젯은 그렇지 않았습니다. 완전히 SPA 가능, 큰 메모리 누수가 발생합니다. 새보기로 이동하기 전에 각 SPA 페이지의 모든 PF 위젯을 반복하고 특정 PF 위젯 및 일부 다른 까다로운 시나리오 (폴링, 유휴 타이머, 키 바인딩 ... 비활성화)에 대한 이벤트를 수동으로 바인드 해제해야합니다. 지금까지 큰 문제없이 JSF 2.2를 PrimeFaces 및 SPA 방식으로 사용하고 있다고 말할 수 있습니다. –

+0

안녕하세요 Maikel (및 Kukeltje) - 귀하의 경험과 옵션에 대해 감사드립니다. 이 SPA 접근법이 실제 세계에서 작동한다는 것을 알게되어 기쁩니다. 우리는 ViewScopedBean (표준 JSF 2.3의 ViewScopedBean이 아닌 모든 POST/GET 요청 이후에 파기 됨)을 사용하여 Omnifaces (Tomcat에서 이전에 CDI를 소화해 냈습니다)를 사용하기 시작했습니다. 이제 SPA 방식의 Omnifaces/ViewScopedBean을 사용할 수 있습니다. 나는 그것이 좋은 선택이라고 희망한다. – Radek