2014-06-18 1 views
-1

J'ai un projekt JSF et là j'ai différentes vues, qui sont supportées par ManagedBeans.injection ou routage de vue dynamique

Ce que je voudrais accomplir est de changer certaines vues tandis que d'autres restent où elles sont. Cela doit se faire de manière dynamique. En d'autres termes. Je souhaite injecter et supprimer des vues d'une page xhtml sans actualisation de page. Je n'ai aucune idée de comment y parvenir.

Encore mieux serait une injection de vue dynamique basée sur les URL. Angularjs le fait très bien. Mais même sans routage ce serait génial.

Merci d'avance.

Voici un exemple dans le code pseudo:

<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

Que voulez-vous dire par "injection de vue"? S'il vous plaît, fournissez un exemple pour l'explication. Rappelez-vous également que JSF est un framework côté serveur qui génère simplement du code HTML. Vous pouvez le combiner avec Angular sans problème. –

+0

a changé ma question pour être plus clair. – arkhon

Répondre

1

Ce que vous demandez est mieux fait en utilisant Facelet templating. Vous pourrez ainsi avoir un modèle de page avec le contenu partagé (le menu de navigation dans votre cas) et hériter du reste des vues.

Que puis-je voir à partir de votre solution suggérée est que vous abusez des appels POST. #{fragmentsPresenter.changeView('viewOne')} n'a pas de sens juste parce que vous savez déjà où vous voulez aller quand vous appuyez sur ce lien (à viewOne), donc vous serez mieux en utilisant des liens simples pour cela.

Ici vous avez un exemple montrant comment gérer la navigation de manière appropriée. Supposons que vous avez un contrôleur de vue même vous en aurez pas besoin dans la plupart des cas:

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"; 
     } 
    } 
} 

emploi de ce contrôleur est juste pour vérifier ce que vous venez vue de et passer à l'autre. Il est inutile d'effectuer une requête POST (pour envoyer un formulaire) juste pour naviguer vers l'autre vue, alors que vous pourriez l'évaluer avant le rendu de la page.

Vous avez comment la vue du modèle est construit:

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> 

Cette page modèle définit un bouton partagé/set de lien et appelle pour le contenu. J'ai implémenté différents types d'options de navigation. L'utilisation de <h:link /> est, dans ce cas, la manière la plus directe. Vérifiez le deuxième lien, ici nous évaluons l'ID de vue en cours quand il est rendu et un lien pour aller à l'opposé est créé. Cool, n'est-ce pas?

Maintenant, voici c'est la mise en œuvre des vues de l'enfant:

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> 

Vous serez en mesure de taper leur adresse dans votre navigateur et les voir, c'est ce qu'on appelle bookmarkable ;-)

Voir aussi:

+0

Est-il possible de rendre seulement avec ajax? comme il est, il rafraîchira toute la page que j'essaie d'éviter. – arkhon

+0

Il est possible de concevoir quelque chose de similaire à votre solution affichée, avec une page statique et un contenu central rendu à l'aide d'Ajax. Cependant, gardez à l'esprit que, comme je l'ai déjà dit, les requêtes GET sont recommandées pour la navigation de page à page. Les publications Ajax sont un outil pratique pour actualiser le contenu de la vue actuelle ou envoyer des données de formulaire partiel. Mon conseil est d'éviter Ajax pour un usage différent. L'autre choix pourrait être d'utiliser 'ui: include' sans Ajax, mais je pense que les templates sont de loin la meilleure solution pour votre cas. Essayez-les. –

+0

je le ferai. merci pour toute votre aide. – arkhon

0

Ok, je l'ai résolu comme suit:

mon avis:

<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> 

et mon 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

Eh bien, cela semble une bonne solution. Cependant, juste une question, est-ce commandLinks un genre de menu pour la navigation entière de votre application? Si oui, alors vous devriez aller avec la modélisation, je considère qu'il est beaucoup plus utile que de rendre la même vue une fois et encore que vous le faites. Principalement parce qu'il vous fournit des URL bookmarkable. –

+0

merci pour votre réponse, je vais chercher dans le modèle. – arkhon

+0

Je serais en mesure de vous fournir un exemple de coup d'envoi si vous le souhaitez. –