2014-06-18 67 views
-1

我有一個JSF項目,並在那裏我有不同的意見,這是由ManagedBeans支持。動態視圖注入或路由

我想實現的是改變一些視圖,而其他人保持他們在哪裏。這必須動態發生。換一種說法。我想在不刷新頁面的情況下從xhtml頁面注入和刪除視圖。我不知道如何做到這一點。

更好的是基於URL的動態視圖注入。 angularjs做得非常好。 但即使沒有路由,它會很好。

在此先感謝。

這裏是僞代碼的例子:

<nav> 
    <h:link action="navigationBean.changeView(view1)" method="ajax">Link1</h:link> 
    <h:link action="navigationBean.changeView(view2)" method="ajax">Link2</h:link> 
</nav> 

<h:viewContainer> 
    // view selected by clicking the nav links should be injected here without page reload 
</h:viewContainer> 
+0

你是什麼意思與 「觀注」?請給出一個解釋的例子。還要記住,JSF是一個只生成HTML代碼的服務器端框架。你可以將它與Angular結合使用,沒有任何問題。 –

+0

改變了我的問題更加清晰。 – arkhon

回答

1

你問的是使用Facelet templating更好地完成。你可以通過這種方式來創建一個帶有共享內容的頁面模板(你的案例中的導航菜單),並讓其餘的視圖繼承它。

從我建議的解決方案中可以看到的是,您濫用POST調用。 #{fragmentsPresenter.changeView('viewOne')}沒有意義,僅僅因爲你已經知道你想要去哪裏,當你按下該鏈接(到viewOne),所以你會更好地使用簡單的鏈接。

這裏有一個示例,顯示如何以正確的方式處理導航。讓我們假設你有一個視圖控制器,即使你不會需要它在大多數情況下:

ViewController.java

/** 
* Give the scope you want to your bean depending on what are your operations 
* oriented to. This example could be @ApplicationScoped as well 
* 
* @author amaeztu 
* 
*/ 
@ManagedBean 
@SessionScoped 
public class ViewController { 

    /** 
    * Just gets the current view path and switches to the other one 
    * 
    * @return 
    */ 
    public String changeView() { 
     String viewId = FacesContext.getCurrentInstance().getViewRoot() 
       .getViewId(); 
     if (viewId.equals("/view1.xhtml")) { 
      return "/view2"; 
     } else { 
      return "/view1"; 
     } 
    } 
} 

該控制器的工作就是檢查你打算什麼看法從和切換到另一個。執行POST請求(發送表單)僅用於導航到其他視圖是毫無意義的,而您可以在頁面呈現之前對其進行評估。

在這裏你有怎樣的模板視圖建:

的template.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html"> 
    <h:head /> 

    <h:body> 
     <h:form> 
      <!-- Use POST requests like this only when you have 
      to determine the destination dinamically at server side --> 
      <h:commandButton value="Switch View with POST" 
       action="#{viewController.changeView}" /> 
      <br /> 
     </h:form> 
     <!-- For plain navigation, use GET requests --> 
     <h:link value="Go to view 1" outcome="/view1" /> 
     <br /> 

     <!-- Determine where we are at page rendering time 
      and evaluate the other view path --> 
     <h:link value="Switch view without POST" 
      outcome="#{view.viewId eq '/view1.xhtml' ? '/view2' : '/view1'}" /> 
     <br /> 
     <br /> 
     <ui:insert name="content" /> 
    </h:body> 

</ui:composition> 

這個模板頁面定義了一個共享按鈕/鏈接集,並呼籲內容。我已經實現了不同類型的導航選項。在這種情況下,使用<h:link />是最直接的方式。檢查第二個鏈接,在這裏我們評估當前的視圖ID,當它被渲染並且創建一個到另一個鏈接的鏈接。很酷,不是嗎?

現在,這裏是對兒童實施意見:

view1.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" template="/template.xhtml"> 

    <ui:define name="content"> 
     <!-- Here you could have some @ViewScoped 
     bean managing the content i.e. #{view1Bean} --> 
     View 1 
    </ui:define> 

</ui:composition> 

view2.xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml" 
    xmlns:ui="http://java.sun.com/jsf/facelets" 
    xmlns:f="http://java.sun.com/jsf/core" 
    xmlns:h="http://java.sun.com/jsf/html" template="/template.xhtml"> 

    <ui:define name="content"> 
     View 2 
    </ui:define> 

</ui:composition> 

您可以鍵入他們在你的瀏覽器中的地址,並看到他們,這就是所謂的書籤;-)

參見:

+0

是否有可能只使用ajax呈現?因爲它會刷新我試圖避免的整個頁面。 – arkhon

+0

可以設計類似於您發佈的解決方案的東西,使用Ajax呈現靜態頁面和中心內容。但是,請記住,正如我之前所說的,建議使用GET請求進行頁面到頁面的導航。 Ajax回發是一種方便的工具,用於刷新當前視圖內容或發送部分表單數據。我的建議是避免使用任何不同的Ajax。其他選擇可以使用沒有Ajax的'ui:include',但我認爲模板是迄今爲止您的案例的最佳解決方案。給他們一個嘗試。 –

+0

我會的。 thx爲您的所有幫助。 – arkhon

0

好吧,我解決了這個問題,如下所示:

我的觀點:

<h:body> 

<nav> 
<h:form> 
    <h:commandLink action="#{fragmentsPresenter.changeView('viewOne')}"> 
     viewOne 
     <f:ajax execute="@this" render="fragment-container" /> 
    </h:commandLink> 
    <h:commandLink action="#{fragmentsPresenter.changeView('viewTwo')}"> 
     viewTwo 
     <f:ajax execute="@this" render="fragment-container" /> 
    </h:commandLink> 
</h:form> 
</nav> 

<h:panelGroup id="fragment-container"> 
    <ui:fragment rendered="#{fragmentsPresenter.activeView('viewOne')}"> 
     <div>i am view one!</div> 
    </ui:fragment> 
    <ui:fragment rendered="#{fragmentsPresenter.activeView('viewTwo')}"> 
     <div>i am view Two!</div> 
     <ui:include src="fragment.xhtml"/> 
    </ui:fragment> 
</h:panelGroup> 

和我ManagedBean:

@ManagedBean 
@SessionScoped 
public class FragmentsPresenter { 
    private String activeView; 

    public void setActiveView(String viewName) { this.activeView = viewName; } 
    public String getActiveView() { return this.activeView; } 

    public FragmentsPresenter() { this.activeView = "viewOne"; } 

    public void changeView(String viewName) { this.activeView = viewName; } 

    public boolean activeView(String viewName) { 
     return activeView.equals(viewName); 
    } 
} 
+0

好吧,這似乎是一個合適的解決方案。然而,只是一個問題,commandLink是您整個應用程序導航的一種菜單嗎?如果是的話,那麼你應該採用模板化,我認爲它比一次又一次地呈現相同的視圖更有用。主要是因爲它爲您提供了可收藏的網址。 –

+0

感謝您的回覆,我會研究模板。 – arkhon

+0

如果你願意,我將能夠爲你提供一個開創性的例子。 –