在我的代碼庫中過去不好的日子裏,我們非常依賴事件重新計算,我懷疑這是由於ICEfaces或MyFaces中的實現細節而非標準指定的行爲。我們使用頻繁做的一件事是這樣的事情:JSF:在值更改後調用動作
<ice:inputText value="#{bb.frequency}" valueChangeListener="#{bb.valueChanged}"/>
的目標是安排retune
到setFrequency
每當頻率改變後調用。
然後我們在backing bean中有一些相當令人厭惡的代碼,它會重發事件。它通常看起來像這樣:
class BB {
// this happens first, thanks to UPDATE_MODEL_VALUES
public void setFrequency(Frequency f) {
this.model.f = f;
}
public void valueChanged(ValueChangeEvent event) {
if (event.getOldValue().equals(event.getNewValue())
return; // nothing changed, so leave
if (FacesContext.getCurrentInstance().getPhaseId() != INVOKE_APPLICATION) {
OurMagicEventUtils.requeueEvent(event, INVOKE_APPLICATION);
}
else {
// do the post-setter work here (the setter happened recently during
// UPDATE_MODEL_VALUES so we're up-to-date by here
this.model.retune();
}
}
}
這不是一個好的生活方式。我還沒有找到一種可靠的方法來爲以後的階段重新制定事件,顯然這不是人們所做的事情。我看到兩種解決方案:
將重調智能移動到
BB#setFrequency
方法。在許多情況下,我無法擺脫這種情況,因爲我直接處理較低級別的模型類,而且我不想幹擾其他客戶的行爲。
創建一個自定義組件並將邏輯移動到那裏的
setFoo
方法。我不喜歡這個,因爲在嵌入其他容器時,Mojarra和自定義組件有很多問題。對於我需要做的事情來說,這看起來似乎有點矯枉過正 - 我確實需要在設置一些屬性後調用
retune
。創建支持bean的所有東西。直接將大多數方法委託給內部事物,但趕上
setFoo
並在那裏執行重新調節。這與我們以前做的非常相似,它意味着很多樣板,包裝和膠水代碼,所以我不喜歡它。
在我心目中,我想象這樣的事情:
<ice:inputText value="#{bb.frequency}" afterChange=#{bb.retune}"/>
但是這顯然是行不通的,因爲也需要一個類名,但沒有關聯,無論你」會附加一個<f:actionListener>
目前正在做,而且它只能在UICommand
之間設置,其中UIInput
不是。
什麼是解決這種困境的優雅/正確的方法?
再次感謝您的直接回答。你如何建議有人真正學習JSF?我覺得我在網絡上學習點點滴滴,但即使經過三年專業使用,我仍然有許多空白。除S.O.之外,我應該如何解決這些差距? –