Domanda

Ci sono un paio di cose che ho difficoltà a comprendere riguardo allo sviluppo di componenti personalizzati in JSF.Ai fini di queste domande, puoi presupporre che tutti i controlli personalizzati utilizzino associazioni di valori/espressioni (non associazioni letterali), ma sono interessato anche a spiegazioni su di esse.

  1. Dove posso impostare il valore per il valuebinding?Dovrebbe succedere in decodifica?Oppure la decodifica dovrebbe fare qualcos'altro e quindi impostare il valore in encodeBegin?
  2. Leggi dal valore vincolante: quando leggo i dati dal valore vincolante e quando leggo i dati dal valore vincolante?leggendolo dal valore inviato e inserendolo nel valuebinding?
  3. Quando vengono chiamati gli action listener sui moduli in relazione a tutto ciò?Tutte le pagine del ciclo di vita JSF menzionano eventi che si verificano in vari passaggi, ma non mi è del tutto chiaro quando viene chiamato solo un semplice ascoltatore per un pulsante di comando

Ho provato alcune combinazioni, ma alla fine mi ritrovo sempre con bug difficili da trovare che credo derivino da incomprensioni di base del ciclo di vita dell'evento.

È stato utile?

Soluzione

C'è un diagramma abbastanza buono in Specifica JSF che mostra il ciclo di vita della richiesta, essenziale per comprendere queste cose.

I passaggi sono:

  • Ripristina vista.L'albero UIComponent viene ricostruito.
  • Applica i valori della richiesta.I componenti modificabili dovrebbero implementare EditableValueHolder.Questa fase percorre l'albero dei componenti e chiama il file processDecodes metodi.Se il componente non è qualcosa di complesso come un UIData, non farà molto se non chiamarlo proprio decodificare metodo.IL decodificare Il metodo non fa molto se non trovare il suo renderer e invocarlo decodificare metodo, passando se stesso come argomento.È compito del renderer ottenere qualsiasi valore inviato e impostarlo tramite setSubmissionValue.
  • Convalide del processo.Questa fase chiama processValidators che chiamerà convalidare.IL convalidare Il metodo prende il valore inviato, lo converte con qualsiasi convertitore, lo convalida con qualsiasi validatore e (supponendo che i dati superino tali test) chiama valore impostato.Ciò memorizzerà il valore come variabile locale.Anche se questa variabile locale non è nulla, verrà restituita e non il valore dall'associazione valore per qualsiasi chiamata a getValore.
  • Aggiorna valori del modello.Questa fase chiama processoAggiornamenti.In un componente di input, questo chiamerà aggiornamentoModel che otterrà il ValoreEspressione e invocarlo per impostare il valore sul modello.
  • Richiama l'applicazione.Qui verranno richiamati gli ascoltatori di eventi dei pulsanti e così via (così come la navigazione, se la memoria serve).
  • Rendering della risposta.L'albero viene renderizzato tramite i renderer e lo stato viene salvato.
  • Se una qualsiasi di queste fasi fallisce (ad es.un valore non è valido), il ciclo di vita passa a Render Response.
  • Vari eventi possono essere attivati ​​dopo la maggior parte di queste fasi, richiamando i listener in modo appropriato (come i listener di modifica del valore dopo le convalide del processo).

Questa è una versione un po’ semplificata degli eventi.Fare riferimento alle specifiche per maggiori dettagli.

Mi chiederei perché stai scrivendo il tuo UIComponent.Questo è un compito non banale e per farlo bene è necessaria una profonda conoscenza dell'architettura JSF.Se hai bisogno di un controllo personalizzato, è meglio creare un controllo concreto che estenda un componente UI esistente (come fa HtmlInputText) con un renderer equivalente.

Se la contaminazione non è un problema, esiste un'implementazione JSF open source sotto forma di Apache MyFaces.

Altri suggerimenti

Ascoltatori di azioni, come ad esempio a Pulsante di comando, vengono chiamati durante il Richiama l'applicazione fase, che è l'ultima fase prima della finale Rendering della risposta fase.Questo è mostrato in Il ciclo di vita di JSF - figura 1.

È l'unico framework che abbia mai usato in cui la creazione di componenti è un processo profondo intricato come questo.Nessuno degli altri quadri web (nel mondo .NET o no) lo rende così doloroso, il che è completamente inspiegabile per me.

Alcune delle decisioni progettuali alla base di JSF iniziano ad avere più senso se si considerano gli obiettivi.JSF è stato progettato per essere attrezzato: espone molti metadati per gli IDE.JSF non è un framework web: è un file MVP framework che può essere utilizzato come framework web.JSF è altamente estensibile e configurabile: puoi sostituire il 90% dell'implementazione in base all'applicazione.

La maggior parte di queste cose rendono il tuo lavoro più complicato se tutto ciò che vuoi fare è inserire un controllo HTML aggiuntivo.

Il componente è una composizione di diversi componenti di base di InputText (e altri), btw.

Presumo che i frammenti di pagina JSP-include/basati su strumenti non soddisfino i tuoi requisiti.

Prenderei in considerazione l'utilizzo del tuo UIComponentELTag.createComponent per creare un controllo composito con una base UIPanel e creare tutti i suoi figli da implementazioni esistenti.(Suppongo che tu stia utilizzando JSP/taglib e facendo qualche altra ipotesi.) Probabilmente vorresti un renderer personalizzato se nessuno dei renderer UIPanel esistenti facesse il lavoro, ma i renderer sono facili.

Il miglior articolo che ho trovato è Scrittura di componenti Jsf, per quanto


public String getBar() {  
     if (null != this.bar) {  
         return this.bar ;  
     }  
     ValueBinding _vb = getValueBinding("bar");  
     return (_vb != null) ? (bar) _vb.getValue(getFacesContext()) : null;  
}
  

come è arrivato a getValueBinding?Nel metodo setProperties della classe tag

  if (bar!= null) {  
         if (isValueReference(bar)) {  
             ValueBinding vb = Util.getValueBinding(bar);  
             foo.setValueBinding("bar", vb);  
         } else {  
             throw new IllegalStateException("The value for 'bar' must be a ValueBinding.");  
         }  
     }  
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top