2013-10-30 118 views
0

更新:對於那些將此標記爲重複關閉的標記,所假定的重複問題與我所要求的無關。我的問題是我不知道,直到渲染時間什麼問題集,會有多少問題或什麼問題類型將是,所以我不能使用「可能的重複」答案中描述的技術。JSF 2.0動態表單最佳實踐

我們的JSF 2.x應用程序的一部分需要將問題集呈現給用戶,問題和問題類型直到運行時才知道。例如,我們有這樣的事情(爲清楚起見省略getter/setter方法):

public class QuestionSet { 
    private List<Section> sections; 
} 

public class Section { 
    private String sectionTitle; 
    private List<Question> questions; 
    private SectionStatus status; // e.g. UNANSWERED, CURRENTLY_ANSWERING,ANSWERED, COMPLETED 
} 

public class Question { 
    private String questionText; 
    private QuestionType questionType; // E.G TEXT, RADIO, LIST, CHECKBOX 
    private List<String> options; // for RADIO/LIST/CHECKBOX types 
    private List<String> answers; 
} 

我們需要呈現在一個單獨的DIV每個部分,這取決於它的狀態(例如未回答將顯示一個div只是標題,就問會顯示帶有部分標題和綠色刻度標記的div,CURRENTLY_ANSWERING將使用部分標題呈現div,然後使用基於問題類型的適當輸入控件顯示每個問題。

問題在運行期間也是動態的 - 例如,如果用戶對單選按鈕問題回答「是」,則可能會提示更多的子問題。

我目前做這個用結合,即

<h:panelGroup binding = "#{bean.panelGroup}" /> 

和bean的getPanelGroup內的ValueExpressions等,它們工作正常,但在閱讀一些BalusC的的手工創建全光照的事情組件樹像HtmlPanelGroup,HtmlOutputText,UIInput回答,特別是對這個問題:How does the 'binding' attribute work in JSF? When and how should it be used?我想知道是否有一個「更好」的方法?

我關心的一件事是,在RECREATE_VIEW期間因爲鏈接問題中解釋的原因(在調用綁定中引用的方法之後)調用getter,所以除非我採取步驟在RECREATE_VIEW階段中僅返回我在上一個RENDER_RESPONSE階段創建的組件,這會導致重新創建我剛創建的東西的不必要花費。

在這種情況下,JSF調用我的setter來設置我剛纔在綁定屬性的getter中設置的東西似乎毫無意義。 (我的bean是視圖範圍內,我將需要使用AJAX對於一些我們的用戶需要的功能)

思想/意見(尤其是從以往任何時候都很有幫助BalusC)不勝感激...

+0

[JSF:動態更改窗體]的可能重複(http://stackoverflow.com/questions/5654269/jsf-dynamically-change-form) – 757071

+0

有關如何綁定工作檢查的詳細信息:http://stackoverflow.com/questions/14911158/how-binding-attribute-in-jsf-works – 757071

+0

@johny,我不希望聽起來那麼尖銳,但你還沒有正確地閱讀我的問題。這是最肯定不是你的評論中的第一個鏈接的重複 - 正如我所說,我不知道,直到我查詢數據庫有多少問題會有什麼問題類型將是,所以我不能在你的wy中使用ajax 「可能的欺騙」問題。此外,我在我的文本中鏈接到相同的綁定文章!事實上,這是什麼促使我的問題。 –

回答

1

我不看到在這種情況下使用組件綁定的很多理由。您可以在視圖中決定要渲染什麼以及如何渲染。你可以有<ui:fragment>/<c:if>有條件地呈現基礎上問題類型的元素,<ui:repeat>/<c:forEach>來處理問題集等

所以,如果我理解正確的工作流程,你的問題集將在例如確定後期構造方法:

@PostConstruct 
public void init() { 
    questionSet = service.get();//get it somehow 
} 

然後你就會有一組部分,每個部分,這些將包含的問題,或答案,有效性是通過AJAX進行檢查。如果我理解你的權利,那麼你可以有以下幾種觀點:

<h:form id="q-set"> 
    <ui:repeat value="#{bean.questionSet.sections}" var="section"> 
     <div>#{section.title}</div> 
     <div class="#{section.status eq 'UNANSWERED' ? 'section-unanswered' : ... }"/> 
     <ui:fragment rendered="#{section.status eq 'ANSWERED' ?}"><div class="tick"/></ui:fragment> ... 
     <ui:fragment rendered="#{section.status eq 'ANSWERED' ?}"> 
      <ui:repeat value="#{section.questions}" var="question"> 
       <div>#{question.title}</div> 
       <ui:fragment rendered="#{question.type eq 'RADIO'}"> 
        <h:selectOneRadio value="#{question.answers[0]}" validator="..."> 
         <f:selectItems value="#{question.options}" var="opt" itemLabel="#{opt}" ... /> 
         <f:ajax ...> 
        </h:selectOneRadio> 
       </ui:fragment> 
       ... 
      </ui:repeat> 
     </ui:fragment> 
    </ui:repeat> 
</h:form> 
+0

不!再一次,我不知道問題的類型會是什麼!所以在你的情況下,你已經顯示了一個selectOneRadio,但它可能是一個h:inpuText或一個h:selectBooleanCheckbox或一個h:selectOneMenu等等,並且這個集合中的每個問題都可能是不同的類型。例如,我可以得到「你喜歡貓嗎?」單選按鈕問題,然後是「你的貓是什麼顏色?」需要一個下拉列表,然後是一個「請評論」,這需要一個輸入文本框。或者我可以得到「你最喜歡的3個餅乾是什麼?」和一個cookie選項的複選框列表,然後「你多大了?」下拉列表等。 –

+1

您是否在內部迭代組件中看到省略號?您需要在其中放置另一個片段,以便涵蓋每個問題類型,並因此根據問題類型呈現每個HTML DOM元素。例如。 ''' ui:fragment rendered =「#{question.type eq'DROPDOWN'}」>'等 – skuntsel

0

它看起來像你將有太多的邏輯/條件在您的視圖。

如何在Java端生成視圖programmatically

對於棘手的部分,您可以使用JavaScript和JSON。

+0

這就是我現在正在做,我正在詢問關於是否有「更好」的方式的意見:) –

+0

我必須承認我不是JSF的高度動態形式的粉絲......在某些情況下,我只是使用JavaScript/JSON而不是純粹的JSF/Facelets解決方案。 –